Skip to content

Git 高级

2. 放弃提交

放弃上一次提交:

bash
git reset --soft HEAD^
# 或者
git reset --soft HEAD~1

放弃若干次提交,~ 后的数字代表你想放弃的次数:

bash
git reset --soft HEAD~2
放弃提交示例

放弃提交,保留 Add:

bash
git reset --soft HEAD^

暂存修改:

bash
git stash

签出历史提交:

bash
git checkout $COMMIT_ID

最后恢复工作进度:

bash
git stash pop

3. 克隆

3.1 指定克隆深度

Git 选项 --depth 选项用于指定克隆深度,即保留之前多少次提交,一般克隆项目只用于测试或部署而不需要开发,就不需要保留历史,因为克隆历史需要占用大量网络资源,也会占用不必要的空间。例如:

bash
git clone --depth 1 https://github.com/python/cpython.git

3.2 指定分支

Git 选项 --branch 用于指定分支,如果只需要单个分支也可以使用 --single-branch 选项,默认将选择 origin 分支。例如:

bash
git clone --branch v1.0 https://github.com/python/cpython.git

3.3 递归克隆

如果项目中有子模块,可以使用 --recursive 选项递归克隆:

bash
git clone --recursive https://github.com/python/cpython.git

4. 标签

可以给某个提交号加标签,即将 tag 绑定到 commit 上。例如:

bash
git tag -a v1.2.3 $COMMIT_ID -m "Release v1.2.3"

其中 $COMMIT_ID 可以是完整的 commit ID,也可以是简写的 commit ID,可通过如下命令获取:

bash
git rev-parse --short HEAD

打上 tag 后需要将 tag 上传到远程仓库:

bash
git push origin v1.2.3

如果需要上传全部的 tag,可以一次性上传全部:

bash
git push origin --tags

5. 删除一个文件的全部历史

危险操作

这个操作会改变仓库的全部历史,并使得其他用户的历史树失效。如果你不是仓库的唯一使用者,建议谨慎使用。

有时我们错误地将一个大文件或敏感文件提交到了 Git 仓库,我们不得不在历史中删除这个文件的全部记录,这是万不得已的操作。

确保当前没有未保存的更改:

bash
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch $YOUR_FILE_PATH" --prune-empty --tag-name-filter cat -- --all

现在将全部记录重新上传:

bash
git push origin --force --all
git push origin --force --tags

对仓库执行垃圾回收:

bash
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now

6. 删除云端不存在的本地分支

有时候我们在本地创建了分支,但是在远程仓库中没有,这时候我们需要删除这个本地分支:

bash
git remote prune origin

8. 安全的强制提交

使用 git push --force 会强制提交,但是这样会覆盖远程仓库的提交,导致他人的提交被覆盖。

参数 --force-with-lease 参数自 Git 的 1.8.5 版本开始提供,旨在解决 git push --force 命令造成的安全问题。