Windows Git
2023-10-15
使用 WSL 的时候 git 用得简直令人难受,每次切换环境(Windows 和 WSL),都需要 Refresh Index,一次就得二十几秒。
最后只好搞一个别名:
# 5.15.90.1-microsoft-standard-WSL2
if [[ "`uname -r`" == *WSL2 ]]; then
SHMODE=wsl
fi
if [[ $SHMODE == "wsl" ]]; then
alias git=git.exe
fi
这是我的本地环境中截出来得一点,其实还做了一些其他得适配,总算能够接受了。
原因
暂时没有读到相关资料。
WSL 已经出来很久了,可是这些性能问题微软还是没有解决,可能是他们不想解决。
参考资料与拓展阅读
Git
2023-04-26
开源中国文章 紧跟 AI 步伐, Gitee 已支持 AI 模型托管 中介绍了 Git LFS 的使用。
结合 git lfs help,记录如下:
- 需要先 install 一下,启用 LFS 功能
$ git lfs install
Updated Git hooks.
Git LFS initialized.
- 追踪大文件
git lfs trace path/to/largefile
# 会记录在 .gitattributes 文件中
# path/to/largefile filter=lfs diff=lfs merge=lfs -text
- 推送大文件
# 正常提交
git add .gitattributes path/to/largefile
git commit -m "..."
# 推送
git lfs push --all
git lfs push --all origin
- 拉取大文件
git lfs pull --all
# 指定文件
git lfs pull -I <filepath>
git lfs ls-files
列出大文件
Git
2023-03-13
看到一篇公众号文章 《Git仓库迁移实操(附批量迁移脚本)》,介绍他们将 GitLab 中一个 Group 内的几十个项目迁移到另一个 Group。
PS:文章有提到,前提是无法得到管理员协助,开启创建时导入的功能。
git clone
& git push
&& git push --tags
git clone --mirror
&& git push --mirror
git clone --bare
&& git push --mirror
基本方法就是 clone && push,不过参数不同。
只是,我没有了解过这里说的 --mirror
参数,这里记录一下,用到的时候研究研究。
文章带了两个脚本:
#!/bin/bash
remote_old=git@host1:group1
remote_new=git@host2:group2
while read repo
do
echo $repo
git clone --bare "$remote_old/${repo}.git"
cd "${repo}.git"
git push --mirror "$remote_new/${repo}.git"
cd ..
rm -fr "${repo}.git"
done < repos.txt
@echo off
set remote_old=git@host1:group1
set remote_new=git@host2:group2
set input_file=repos.txt
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ %input_file%"`) do (
call :process %%a
)
goto :eof
:process
SETLOCAL EnableDelayedExpansion
set "repo=!%1!"
set "repo=!repo:*:=!"
echo !repo!
git clone --bare "%remote_old%/!repo!.git"
cd "!repo!.git"
git push --mirror "%remote_new%/!repo!.git"
cd ..
rmdir "!repo!.git"
ENDLOCAL
goto :eof
Git
2023-01-10
看了一篇文章 What makes Git so hard to use? 在吐槽 Git 难用。
看完之后发现是软广,作者是想推荐自己公司的产品 HighFlux。我看了一下,似乎是通过封装和自动化来达到简化操作的目的。
我用 Git 几年了,不敢说熟练掌握,但是绝对可以说足以应付工作中的所有场景。
我逐条分析一下作者的观点:
Git commands are too many, too low-level and hard to understand.
作者认为,Git 有 157 个命令,让人觉得自己永远是初学者。
我的观点:只需要掌握常用的一些命令就够了,不需要了解那些底层命令。
底层命令是为其他的场景创造更多可能性。
但是确实可以改进一下:大部分人只需要关心十个左右的上层命令就行了,所以可以在产品上提供一些区分,比如分成 git-core / git-full。
好像也没啥意义,算了。
Git tracks 4 versions of files, instead of just "my" version and "the team's" version.
Git 管理文件的四种状态:除了本地版本,远程版本之外,还要学习 stash 和 index(staging area)。
我更加不敢苟同了,这应该正是 Git 强大的地方啊。
Stash 你不喜欢不用就是了。
Index 去掉似乎是可以少一个步骤,直接提交到本地仓库,对于非专业的人来说,减少一点点心智消耗。
sequenceDiagram
WorkingDirectory ->> Index(StagingArea) : add
Index(StagingArea) ->> LocalRepo : commit
LocalRepo ->> RemoteRepo : push
WorkingDirectory ->> + StashArea : stash
StashArea ->> - WorkingDirectory : stash pop
Git doesn't let us safely experiment
作者说了三个功能的缺失:
- undo,就是所有操作的一个回退
- dryrun
- 丢失本地更新的操作,比如
git reset --hard
应该加一个确认
好像有点道理,对于非专业的人来说,这样是会友好些。
但是非专业的人是不是一般都用 GUI,这个事情 GUI 来做似乎完全没有问题啊!
我很少用 GUI 来执行什么操作(只使用 gitg 查看历史),所以对 Git GUI 生态不太了解。
这个意思是不是说 Git 缺少一个好用的 GUI?
Git 开发工具
2022-01-17
读到微信公众号文章 本地如何配置多个 GitHub/Gitee 账号?,想起了几年前,面对这样的需求,我自己也是这么操作的。
Git 开发工具
2021-08-04
看到有篇文章说是 git “新增”了 switch 和 restore 两个命令,仔细一看,原来就是 2019 年就引入了的两个命令,不过我确实没有用过。
这里重新整理一下现在 git 的命令。
git version
git version 2.30.2
apt list --installed | grep ^git
git-doc/hirsute,hirsute,now 1:2.30.2-1ubuntu1 all [已安装]
git-extras/hirsute,hirsute,now 6.1.0-1 all [已安装]
git-flow/hirsute,hirsute,now 1.12.3-1 all [已安装]
git-man/hirsute,hirsute,now 1:2.30.2-1ubuntu1 all [已安装,自动]
git-svn/hirsute,hirsute,now 1:2.30.2-1ubuntu1 all [已安装]
git/hirsute,now 1:2.30.2-1ubuntu1 amd64 [已安装]
gitg/hirsute,now 3.32.1-1 amd64 [已安装]
gitk/hirsute,hirsute,now 1:2.30.2-1ubuntu1 all [已安装]
Git
2021-07-05
今天注意到了 git push 的一个参数 --force-with-lease
,可以在 Remote 有更新的时候不执行强推。
我之前考虑过会有这样的情况发生:我准备强推之前,会做最后一次拉代码检查,无误之后 force push。但是这个检查和 push 之间有一个时间差,会不会在这期间有别的小可爱提交了代码呢?
这种情况是完全可能存在的,就像是线程安全问题,只是团队的规模消减了我对这种情况的担心。
但是 --force-with-lease
参数可以彻底化解我的这种担忧,我决定以后就改用这个参数了。
Git 项目管理
2021-04-07
Git Flow
荷兰程序员 Vincent Driessen 2010 年提出。
PDF 下载
- master 主干
- develop 开发分支
- feature/xxx 功能开发分支(临时)
基于 develop 创建,开发完成之后:合并到 develop 分支,删除
- release/xxx 预发布分支(临时)
基于 develop 创建,测试通过之后:合并到 master 分支,打 tag,合并到 develop 分支,删除
- hotfix/xxx 问题修复分支(临时)
基于 master 创建,问题修复之后:合并到 master 分支,打 tag,合并到 develop 分支,删除
特点:基于版本交付
PS: 作者于 10 年后,也就是 2020 年,更新了一次,表示:对于互联网应用的开发应该考虑更加简单的工作流,比如 GitHub Flow。但不管怎样,应该结合自身的实际情况,不能盲目照搬。
GitHub Flow
- 从 master 拉分支,提交,推送
- pull request
- 评审,测试
- merge 到 master
特点:基本不涉及项目的分支管理,主要是对多人协作方式提出建议:Pull Request。适合多人参与的开源项目,由项目管理员负责维护主干。
中间可以借助自动化工具来静态分析、部署、测试,提升开发速度。但这些工具不是 GitHub Flow 专有,或者说不是它的特色。
这套逻辑看似非常简单,但要硬套到企业项目开发流程中可能会非常复杂,水土不服。
PS: 虽然 git 新增了一个 request-pull 子命令,但可能很鸡肋,不可能脱离 Web 来参与讨论、评审代码。
GitLab Flow
分不同环境:
- master 开发分支,管理方式就是 GitHub Flow,不过就是 Pull Request 改名为了 Merge Request
- pre-production 预发布分支,只能从 master 合并
- production 发布分支,只能从 pre-production 合并
如果需要发布:
- 从 master 拉分支,比如:
20-04-stable
,创建语义化版本号。
- 如果后期有严重 BUG,可以从 master cherry-pick 过来。
特点:比 GitHub Flow 更进一步,对项目的发布和部署提出了建议,并支持多个环境。
主要是其中有一点特别好的就是: Upstream First, 上游优先。所有环境以及维护分支的提交必须来自 master 分支。
我的思考
当然,还是那句老话:适合自己的就是最好的。
项目分支管理流程要和项目自身的特点,以及团队成员的技术水平相匹配。
Git Flow 的整套流程挺完备的,符合一般开发的习惯,只是对其作出规范而已。
GitHub Flow 也好,GitLab Flow 也好,都可以看做是 Git Flow 的补充。
GitHub Flow 和 GitLab Flow 都假定 master 分支是可发布的,而 Git Flow 从 master 拆分出了一个 develop 作为缓冲,我认为这个设计比较合理。
Git Flow 有几个需要注意的问题:
- 合并的时候保留之前的合并记录,谨慎快进 (
--no-ff
)
- hotfix, release 分支推送到 master 发布之后,切记还要同步推送到 develop 分支
- 必须坚持 master, develop 上不随意推送(还是得靠 Pull Request 机制)
- 如果有不属于当前发布周期需要的开发,不要合并到 develop
- 临时分支必须快用快销,不要长时间保留,且合并之后理解删除
我设想中的开发流程
1,基本参照 Git Flow (借助工具)
上游优先原则:master 分支作为所有可发布环境的上游
2,自动化测试:
- develop, release, master: 只要有变更就触发一次自动化测试
- 此外, master 应该保持一定频率的定时自动化测试
3,老版本需要维护就在 tag 上拉分支。
现实场景中,可能要为 abc 环境上的某个老版本 v1.0.0 修复 BUG、加功能,或对已有功能进行一些调整。
git branch maintain/abc v1.0.0 # 一旦分叉,就需要长期保留该分支
# maintain/abc/develop
# maintain/abc/feature/xxx
# maintain/abc/hotfix/xxx
# maintain/abc/release/xxx
# 视情况,可以简化处理,不用上面这些分支
PS: 最后需要重新发布的时候可以对版本号加上附加的标识 v1.0.0.1.abc
5,如果是 OEM,针对客户有关的信息、资源应该留给打包系统来统一处理
此外:
- 项目应有明确的 roadmap
- 代码评审
- 数据库设计统一管理
- 项目文档,需求库,用例库
- 版本号基本上遵循语义化版本规范
- 提交记录遵循 git commit message 规范 (借助工具)
- CI/CD + 自动化测试
参考资料与拓展阅读
- 阮一峰, Git分支管理策略
- 阮一峰, Git 工作流程
- git-flow 备忘清单
- GitLab, Introduction to GitLab Flow
- GitHub, Understanding the GitHub flow
- GitHub, GitHub Flow
- Git-Tower, git-flow 的工作流程
- 阮一峰, Git 使用规范流程
- 阮一峰, Commit message 和 Change log 编写指南
- 阮一峰, git cherry-pick 教程
- 阮一峰, Git远程操作详解
- 阮一峰, git bisect 命令教程
- 阮一峰, 常用 Git 命令清单
- 廖雪峰, Git教程
- https://github.com/wangdoc/git-tutorial
Git
2020-07-16
创建分支:
git branch <new-branch-name> <commit-id>
git checkout -b <new-branch-name> <commit-id>
删除远程分支:
git push --delete origin dev0404
删除远程已经不存在的分支:
git remote prune origin -n
git remote prune origin
已经合并到指定分支的分支:
git branch --merged master
# -r, --remote
git branch -r --merged master
创建独立分支(空白分支):
git checkout --orphan newbr
合并无关分支:
git merge newbr --allow-unrelated-histories
Git
2020-06-12
搜索提交信息
git log --grep=fix: --oneline --after='2018-07-01' --author=markjour
搜索历史文件
git grep -C3 sign_position $(git rev-list --all)
搜索 diff 内容
git log -G'前置'
git log -G'前置' -p | grep '前置' -C5
git log -G'前置' --oneline --name-status
-S<string> --pickaxe-regex
和 -G<regex>
作用相近,
不过 -S
只会列出搜索内容增删的相关信息,也就是所在行修改了,但是搜索内容没有变化的会忽略