Foreword

之前选过一些资产管理软件,但是都不够好,当时遗漏了Git LFS,这里再补充测试一下

Git LFS

https://github.com/git-lfs/git-lfs

Git LFS的客户端和Git不同,但是可以使用相同的命令完成Git操作,其实LFS的底层原理挺简单,就是通过Git的时候进行回调,如果是LFS匹配的文件就进入到了LFS提交流程

将所有stp结尾的文件,加入到追踪中

git lfs track "*.stp"
git lfs track "*.CATDrawing"
git lfs track "*.CATPart"
git lfs track "*.dxf"
git lfs track "*.igs"

lfs文件追踪是加在.gitattributes文件中的

git add .gitattributes
git commit -m "track *.stp files using Git LFS"

lfs文件追踪是加在.gitattributes文件中的

git add .
git commit -m "add stp"

查看追踪文件

git lfs track

下载包含lsf的仓库时也需要加上lfs的标签

git lfs clone xxxx

更新内容的脚本

unset http_proxy;
unset https_proxy;
git pull origin main
git add .;
echo -e "\033[34m"
read -p "请输入更新内容,按回车键结束:"
echo -e "\033[0m"
git commit -m $REPLY;
git push origin main
echo -e "\033[34m提交完成,按任意键退出\033[0m"
read -n 1
echo 退出

克隆仓库的脚本

unset http_proxy;
unset https_proxy;
echo -e "\033[34m"
read -p "请输入仓库地址,中键复制,按回车键开始克隆:"
echo -e "\033[0m"
git lfs clone $REPLY;

git push origin main
echo -e "\033[34m提交完成,按任意键退出\033[0m"
read -n 1
echo 退出

创建新仓库脚本

unset http_proxy;
unset https_proxy;
git init --initial-branch=main

git lfs track "*.stp"
git lfs track "*.CATDrawing"
git lfs track "*.CATPart"
git lfs track "*.dxf"
git lfs track "*.igs"
git add .gitattributes
git commit -m "track files using Git LFS"

echo -e "\033[34m"
read -p "请输入仓库地址,中键复制,按回车键开始上传:"
echo -e "\033[0m"

git remote add origin $REPLY

git add .
git commit -m "initial repository commit"
git push origin main
echo -e "\033[34m提交完成,按任意键退出\033[0m"
read -n 1
echo 退出

迁移

把原来git代码中大文件变成lfs中存储

git lfs migrate import --include="*.stp" --everything
git lfs migrate import --include="*.igs" --everything

迁移以后需要强制push,否则无法更新远端

问题

$ git push -u origin master
Remote "origin" does not support the LFS locking API. Consider disabling it with:
  $ git config lfs.https://e.coding.net/xxxx/gitlfs/gitlfs.git].git/info/lfs.locksverify false

可能会出现以上提示,这个是服务端不支持文件锁定,所以需要配置一下让服务端关闭即可

测试

经过测试,1.11GB的文件,比较大的文件加入lfs以后,git add 命令会快很多

上传和下载就取决于网络和服务端限制了,正常使用似乎问题不大。

coding似乎5分钟左右就能完成2.28G的仓库上传,40秒不到就能把整个仓库完全拉下来,完全够用了

大部分硬件仓库和结构仓库,不包含一些七七八八的东西的话,用Git lfs管理足够。

  • 但是coding等一些免费仓库不支持删除lfs文件,这就导致很快那个空间就没有了

配合SourceTree 给小白使用也非常简单

LFS文件评估

由于LFS需要知道具体哪些文件大,我又写了一个脚本和文件模板,直接显示出来比较大文件后缀是什么,然后对应和.gitattributes中的配置对比,看是否已经加入其中了

https://github.com/elmagnificogi/MyTools/tree/master/gitlfs

import os
import re

# use for find all pic in markdown doc

# first get all file
dir = r"J:\GITLFS"
# dir = r"J:\GITLFS\基站3.0"

large_file_list = []


def traverse_folder(path):
    for root, dirs, files in os.walk(path):
        for file in files:
            file_path = os.path.join(root, file)
            file_name = os.path.splitext(file_path)[1]
            # MB
            file_size = round(os.path.getsize(file_path) / 1024.0 / 1024.0, 3)
            # print(file_name, file_size, file_path)

            find_one = False
            for i in range(len(large_file_list)):
                if file_name == large_file_list[i][1]:
                    find_one = True
                    if file_size > large_file_list[i][2]:
                        large_file_list[i][0] = 0
                        large_file_list[i][1] = file_name
                        large_file_list[i][2] = file_size
                        large_file_list[i][3] = file_path
                    else:
                        break

            if find_one == False:
                large_file_list.append([0, file_name, file_size, file_path])


traverse_folder(dir)
sorted_arr = sorted(large_file_list, key=lambda x: x[2])
# for lf in sorted_arr:
#     print(lf[0], lf[1], lf[2])


new_lfs = []
lfs_config_path = r"J:\templete\.gitattributes"
lfr = open(lfs_config_path)
lines = lfr.readlines()
for l in lines:
    name = l.split(' ')[0]
    # print(name)
    nname = name[1:]
    # print(nname)
    for i in range(len(sorted_arr)):
        if sorted_arr[i][1] == nname:
            sorted_arr[i][0] = 1
            break
lfr.close()

for lf in sorted_arr:
    if lf[0] == 0:
        print("未添加 ", str(lf[1]).ljust(12), str(lf[2]).ljust(12) + "MB", lf[3])
    else:
        print("已优化 ", str(lf[1]).ljust(12), str(lf[2]).ljust(12) + "MB", lf[3])

基于此做了一点lfs文件归纳

# picture
*.jpg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.PNG filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text

# doc
*.pdf filter=lfs diff=lfs merge=lfs -text
*.ppt filter=lfs diff=lfs merge=lfs -text
*.pptx filter=lfs diff=lfs merge=lfs -text
*.xls filter=lfs diff=lfs merge=lfs -text
*.xlsx filter=lfs diff=lfs merge=lfs -text
*.doc filter=lfs diff=lfs merge=lfs -text
*.docx filter=lfs diff=lfs merge=lfs -text

*.xml filter=lfs diff=lfs merge=lfs -text
*.scdoc filter=lfs diff=lfs merge=lfs -text

# video
#*.MP4 filter=lfs diff=lfs merge=lfs -text
#*.mp4 filter=lfs diff=lfs merge=lfs -text
#*.avi filter=lfs diff=lfs merge=lfs -text

# double
*.stp filter=lfs diff=lfs merge=lfs -text
*.STP filter=lfs diff=lfs merge=lfs -text
*.step filter=lfs diff=lfs merge=lfs -text
*.STEP filter=lfs diff=lfs merge=lfs -text
*.SLDPRT filter=lfs diff=lfs merge=lfs -text
*.sldprt filter=lfs diff=lfs merge=lfs -text
*.stl filter=lfs diff=lfs merge=lfs -text
*.STL filter=lfs diff=lfs merge=lfs -text
*.igs filter=lfs diff=lfs merge=lfs -text
*.IGS filter=lfs diff=lfs merge=lfs -text

# struct
*.CATDrawing filter=lfs diff=lfs merge=lfs -text
*.CATPart filter=lfs diff=lfs merge=lfs -text
*.CATProduct filter=lfs diff=lfs merge=lfs -text
*.dxf filter=lfs diff=lfs merge=lfs -text
*.dwg filter=lfs diff=lfs merge=lfs -text
*.3dm filter=lfs diff=lfs merge=lfs -text
*.3dxml filter=lfs diff=lfs merge=lfs -text
*.prt.* filter=lfs diff=lfs merge=lfs -text
*.asm.* filter=lfs diff=lfs merge=lfs -text

# simulation
*.lms filter=lfs diff=lfs merge=lfs -text

# other
*.h3d filter=lfs diff=lfs merge=lfs -text
*.op2 filter=lfs diff=lfs merge=lfs -text
*.fem filter=lfs diff=lfs merge=lfs -text
*.x_t filter=lfs diff=lfs merge=lfs -text
*.unv filter=lfs diff=lfs merge=lfs -text
*.dat filter=lfs diff=lfs merge=lfs -text
*.bdf filter=lfs diff=lfs merge=lfs -text
*.wbpz filter=lfs diff=lfs merge=lfs -text
*.mechdb filter=lfs diff=lfs merge=lfs -text
*.acmo filter=lfs diff=lfs merge=lfs -text
*.pmdb filter=lfs diff=lfs merge=lfs -text
*.h5 filter=lfs diff=lfs merge=lfs -text
*.msh filter=lfs diff=lfs merge=lfs -text
*.pack filter=lfs diff=lfs merge=lfs -text
*.fecdb filter=lfs diff=lfs merge=lfs -text
*.wrl filter=lfs diff=lfs merge=lfs -text
*.SLDASM filter=lfs diff=lfs merge=lfs -text
*.hm filter=lfs diff=lfs merge=lfs -text
*.brd filter=lfs diff=lfs merge=lfs -text
*.hm filter=lfs diff=lfs merge=lfs -text
*.SAV filter=lfs diff=lfs merge=lfs -text
*.cgr filter=lfs diff=lfs merge=lfs -text
*.hsf filter=lfs diff=lfs merge=lfs -text
*.minf filter=lfs diff=lfs merge=lfs -text
*.mdd filter=lfs diff=lfs merge=lfs -text
*.cgr filter=lfs diff=lfs merge=lfs -text
*.sim filter=lfs diff=lfs merge=lfs -text
*.mres filter=lfs diff=lfs merge=lfs -text
*.ldsf filter=lfs diff=lfs merge=lfs -text
*.agdb filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.ksp filter=lfs diff=lfs merge=lfs -text
*.xprd filter=lfs diff=lfs merge=lfs -text
*.xpr filter=lfs diff=lfs merge=lfs -text
*.xedz filter=lfs diff=lfs merge=lfs -text
*.bip filter=lfs diff=lfs merge=lfs -text

# *.rst filter=lfs diff=lfs merge=lfs -text
# *.f06 filter=lfs diff=lfs merge=lfs -text
# *.mshdb filter=lfs diff=lfs merge=lfs -text
# *.hm filter=lfs diff=lfs merge=lfs -text

自建LFS服务器

Git LFS,coding里是标配了20G空间,不占用原有代码空间,Gitee里只有1G基本等于没有,必须要私有部署才行

GitLab也支持LFS,不过有一些要求

  • Git LFS is supported in GitLab starting with version 8.2. (gitlab版本需要 >= 8.2)
  • Git LFS must be enabled under project settings (必须在项目设置中开启LFS)
  • Users need to install Git LFS client version 1.0.1 and up (本地git lfs客户端版本 >= 1.0.1)

开源的LFS存储服务器,据说Github也是基于这个二次开发的

https://github.com/git-lfs/lfs-test-server

修改.lfsconfig文件,增加lfs服务器地址

  [lfs]
    url = "http://localhost:8080/"

弹性LFS,使用一些对象存储或者是云盘实现LFS服务

https://github.com/zhxxch/git-lfs-one

Gitea

https://gitee.com/gitea/gitea

Gitea更像是一个简化版的Gitlab,界面干净一些

Gitea和其他DevOps的对比

https://docs.gitea.com/zh-cn/installation/comparison

Gitea整体非常轻量,适合小机器部署,功能自然也缺少了很多,如果人员很少,也没有规模化的一些需求,可以使用Gitea,否则还是Gitlab更好一些

腾讯工蜂

https://code.tencent.com/

通过Ugit发现了腾讯还专门有一个给游戏类使用的管理平台

目前看起来和Coding重叠度非常高,但是给资源的角度非常大方,SaaS版本可以随便使用,LFS仓库给的非常大,可以说很离谱

工蜂的内部界面非常像Gitlab

SVN

https://www.visualsvn.com/

如果只是普通的SVN本地管理是免费的,但是SVN的服务端是收费的

VisualSVN Server

https://www.visualsvn.com/server/

VisualSVN是按照用户数收费的,买断制,所以可以根据人员决定价格,服务器自己出就行了,不过一次性付费只有12个月的更新和维护时间,后续再更新需要再次付费。

VisualSVN也有社区版本,社区版可以给15个人使用

Git UI工具

Ugit

https://ugit.qq.com/zh/index.html

Ugit是腾讯的自研Git客户端,本身分为专业版和美术版,美术版的交互类似SVN一些

Ugit界面相比SourceTree更加简洁一些

默认内置了LFS的模板,适合做大文件管理,内置了文件锁,可以防止文件被多个人更新

Ugit目前适配了私有部署的gitlab,如果此处提示无法登录,注意一下Gitlab的权限是否正常,是否开了代理,有时候代理会导致这里授权失败。

授权以后,可以直接从克隆看到远端仓库,可以直接克隆,还是比较方便的,同时用户信息也自动帮你填好了,上手难度还是降低了一些的

Ugit对比SourceTree,感觉Ugit确实更流畅一些,特别是文件比较多的时候,很明显的感觉,针对性优化确实有点意义

GitKraken

https://www.gitkraken.com/

GitKraken嵌入的比较多,更合适IDE里使用

gitui

https://github.com/extrawurst/gitui

rust写的git ui客户端,主要还是服务VI VIM类的界面

lazygit

https://github.com/jesseduffield/lazygit

和上面的gitui类似,也是服务mac、linux下的终端类界面

SmartGit

https://www.syntevo.com/smartgit/

付费Git客户端,界面类似SourceTree

GitButler

https://gitbutler.com/

gitbutler,交互拉满,各种东西都可以通过拖拽实现,很符合直觉

gitbutler是把修改内容和仓库文件进行了解耦,你修改的文件存在在workspace中,这次提交你可以提交或者融合到任何一个commit或者分支上去,具体怎么融合是他内部帮你处理好,不用自己写命令。

这种适合增量、文件之间耦合关系很弱的开发模式,gitbutler是必须要走PR流程的,如果PR无法正常运行,那么整个流程就走不动了,它不支持你直接合并,这有点奇怪

Summary

大部分情况LFS+Gitlab可以解决多数问题

Quote

https://coding.net/help/docs/admin/pay/newprice.html

https://coding.net/help/docs/repo/git/lfs.html

https://zhuanlan.zhihu.com/p/511750788

https://zhuanlan.zhihu.com/p/146683392

https://gitee.com/help/articles/4235#article-header4

https://forcemz.net/git/2017/04/16/Moses/

https://forcemz.net/git/2018/07/15/GitLFSRethinking/

https://cloud.tencent.com/developer/article/1010589

https://www.escapelife.site/posts/92ef32ff.html

https://juejin.cn/post/6844903791855140872

https://blog.inkroom.cn/2023/02/27/10J1G9S.html