最近跟同学做项目,由于不懂git,多次搞乱分支,遂存档教程留念
https://git-scm.com/book/zh/v2
命令行接口
为了避免重复信息,我们将不会详细解释以下命令行。强烈推荐您阅读 Pro Git 中文版或可以观看本讲座的视频来学习。
基础
git log --all --graph --decorate
: 可视化历史记录(有向无环图)git diff <filename>
: 显示与暂存区文件的差异git diff <revision> <filename>
:显示某个文件两个版本之间的差异
分支和合并
git branch
: 显示分支git branch <name>
: 创建分支git checkout -b <name>
: 创建分支并切换到该分支。相当于git branch <name>; git checkout <name>
git merge <revision>
: 合并到当前分支git mergetool
: 使用工具来处理合并冲突git rebase
: 将一系列补丁变基(rebase)为新的基线git branch --set-upstream-to=<remote>/<remote branch>
:创建本地和远端分支的关联关系git checkout -b newBranch origin/newBranch
新建一个分直跟踪远程分支。加入-B可选参数后会强制创建新分支,并且会覆盖原来存在的同名分支。git checkout [<commit id>] [--] <paths>
主要用于检出某一个指定文件。如果不填写commit id,则默认会从暂存区检出该文件,如果暂存区为空,则该文件会回滚到最近一次的提交状态。git checkout --orphan <new_branch>
基于当前所在分支新建一个赤裸裸的分支,没有任何的提交历史,但是当前分支的内容一一俱全。新建的分支,严格意义上说,还不是一个分支,因为HEAD指向的引用中没有commit值,只有在进行一次提交后,它才算得上真正的分支。git checkout -p <branch>
主要用来比较两个分支间的差异内容,并提供交互式的界面来选择进一步的操作。这个命令不仅可以比较两个分支间的差异,还可以比较单个文件的差异- 如果你之前已经跟踪了
.gitignore
中指定的文件,你需要先从跟踪状态中移除这些文件,这样它们才会被忽略。可以使用命令git rm --cached [文件名]
来移除跟踪状态。
撤销
git commit --amend
: 编辑提交的内容或信息git reset HEAD <file>
: 恢复暂存的文件git checkout -- <file>
: 丢弃修改git restore
: git2.32版本后取代git reset 进行许多撤销操作
git reset:
如果您想要在历史中保留一个“撤销”的记录,可以使用 git revert
- 重置暂存区(Staging Area):将暂存区的更改回退到工作区。
- 重置工作区(Working Directory):放弃工作区的更改。
- 重置提交历史(Commit History):更改提交历史。
使用方式
git reset [file]
:- 仅重置指定文件到暂存区,不影响工作区和提交历史。
git reset
:- 不带任何参数,默认重置整个暂存区,不影响工作区和提交历史。
git reset --soft [commit]
:- 重置当前分支的头部到指定提交,但保留暂存区和工作区,不更改工作区的文件。
- 可以用来撤销一次提交,但保留更改以便重新提交。
git reset [commit]
或git reset --mixed [commit]
:- 默认为
-mixed
,重置暂存区与指定提交一致,但保留工作区的更改。 - 适合于撤销添加到暂存区的更改并重新编辑。
- 默认为
git reset --hard [commit]
:- 完全重置暂存区和工作区,使其与指定提交一致。
- 这会丢失所有自该提交以来在暂存区和工作区的更改。
- 应谨慎使用,特别是在共享分支上。
git reset --keep [commit]
:与
-hard
类似,但在有未提交的本地更改时不会进行重置,以避免丢失更改。
删除分支
git branch -d
更多
git clone --depth=1
: 浅克隆(shallow clone),不包括完整的版本历史信息git add -p
: 交互式暂存git rebase -i
: 交互式变基git blame
: 查看最后修改某行的人git bisect
: 通过二分查找搜索历史记录- git log —oneline —graph
- git diagose storage.py
- 删除未跟踪的文件 git clean -f
进阶内容
git stash
git stash save ""
git stash list, git stash show stash@{0}默认展示第一个
git stash会显示在log中,可以自由在不同的分支间切换。
git blame
显示每一行代码的最后修改记录。它可以帮助你追踪代码的变更历史,了解每一行代码是谁在什么时间进行的修改。这对于调试、代码审查和理解代码变更的背景非常有用。
git blame [options]
-L <start>,<end>
:仅显示文件中从<start>
行到<end>
行的变更记录。-C
:追踪代码块的移动和复制。-M
:追踪代码块的移动。-w
:忽略空白字符的变化。
git filter-branch
一个强大的 Git 命令,用于在历史提交中进行批量重写。它可以用于修改、删除或重写 Git 历史中的提交记录。以下是该命令的详细解释:
git filter-branch
:- 这是一个用于重写 Git 历史的命令。它可以对多个提交进行批量修改。
--force
:- 强制执行命令,即使在某些情况下 Git 会建议不要这样做。它会覆盖已经存在的重写历史。
--index-filter
:- 这是一个用于修改索引(暂存区)的过滤器。它只对索引进行操作,比
--tree-filter
更快,因为它不需要检出工作树。
- 这是一个用于修改索引(暂存区)的过滤器。它只对索引进行操作,比
'git rm --cached --ignore-unmatch ./my_password'
:- 这是一个在index filter中执行的命令:
git rm --cached
:从索引中删除文件,但不删除工作目录中的文件。--ignore-unmatch
:如果文件不存在,则忽略错误。./my_password
:指定要删除的文件路径。在这个例子中,它是./my_password
。
- 这是一个在index filter中执行的命令:
--prune-empty
:- 删除任何在过滤过程中变为空的提交。这样可以保持历史的整洁性。
--tag-name-filter cat
:- 这个选项用于处理标签。
cat
表示保留标签名不变。
- 这个选项用于处理标签。
-- --all
:- 这部分指定过滤的范围:
--
:表示选项的结束,接下来的参数是要处理的分支或其他引用。--all
:表示对所有引用(包括所有分支和标签)进行操作。
- 这部分指定过滤的范围:
这个命令的整体作用是:
- 在 Git 仓库的所有历史记录中,强制删除索引中名为
./my_password
的文件。 - 如果某个提交在删除该文件后变为空提交,则该提交也会被删除。
- 标签名称保持不变。
- 该操作会影响仓库中的所有分支和标签。
缩写
参考 https://www.atlassian.com/blog/git/advanced-git-aliases
caa = commit -a --amend -C HEAD
Which will take all uncommitted and un-staged changes currently in the working directory and add them to the previous commit, amending it before pushing the change up
my_alias = "!f() { 〈your complex command〉 }; f"
类似脚本的写法。
new = !sh -c 'git log $1@{1}..$1@{0} "$@"'
Which will list to screen all new commits have been created with the previous pull.
git subtree add
假设你正在处理一个项目,并希望将另一个 Git 仓库作为子目录引入你的项目中。以下是这个过程的步骤:
示例场景
- 你的主项目名为
MyMainProject
。 - 你想添加的外部仓库的 URL 是
https://github.com/example/ExternalLibrary.git
。 - 你想将这个外部仓库的内容添加到
MyMainProject
的external_lib
子目录中。 - 你想引入外部仓库的
master
分支。
具体步骤
打开终端:打开你的命令行工具。
导航到你的项目目录:
cd path/to/MyMainProject
添加外部仓库作为子树:
git subtree add --prefix=external_lib https://github.com/example/ExternalLibrary.git master --squash
解释:
-prefix=external_lib
指定了外部仓库内容将被放置在你的项目中的哪个子目录。https://github.com/example/ExternalLibrary.git
是外部仓库的 URL。master
指定了你要添加的分支。-squash
是一个可选项,它会将外部仓库的所有提交压缩成一个提交,以简化你的项目历史。
执行命令后,Git 会将指定仓库的内容添加到
MyMainProject
的external_lib
目录中,并创建一个新的提交来记录这个变更。查看子目录:你现在可以在
MyMainProject
的external_lib
目录中看到外部仓库的内容。
git lfs大文件
https://zhuanlan.zhihu.com/p/146683392
git push <remote> <branch>
其中
**-u(或 —set-upstream):**用于将当前分支与远程分支关联起来,使得后续的 git push 或 git pull 命令可以不需要指定分支名称。 —force(或 -f):这个参数用于强制推送 **—all:**这个参数用于推送所有分支到远程仓库。例如:git push —all origin 将所有本地分支推送到远程仓库。
**—tags:**这个参数用于推送标签(tags)到远程仓库。例如:git push —tags origin 将所有本地标签推送到远程仓库。
-n(或 —dry-run):模拟推送操作,不会实际执行推送,但会显示将要推送的更改。
删除远程分支
你可以使用 git push 命令来向远程仓库推送一个空分支,这会导致远程分支被删除。具体步骤如下: 假设要删除名为 remote-branch 的远程分支。 git fetch —prune获取最新的远程分支信息 这将从远程仓库获取最新的分支信息,并清理掉已经不存在的远程分支。 git push origin
将远程分支连接到本地仓库
检查可用的远程分支: 首先,你可以运行以下命令来查看远程仓库中存在哪些分支 git ls-remote —heads
查看分支的合并状态
- 使用 git branch -r —merged这个命令会显示所有已经合并到当前分支的远程分支
- 使用 git log 您也可以检查特定分支的提交是否出现在另一个分支中: git fetch origin git log origin/
..origin/ 使用 git fetch origin 获取最新的远程仓库数据。 使用 git log 命令比较两个分支。如果输出为空,那么 上的提交已经存在于 上。 - 使用 git merge-base 另一种方法是使用 git merge-base: bashCopy code git fetch origin git merge-base origin/
origin/ 这将显示两个分支的最近公共祖先。然后您可以用这个提交哈希与两个分支的最新提交进行比较。 注意事项 在执行这些命令之前,请确保您的本地仓库与远程仓库是同步的,这可以通过 git fetch origin 实现。 检查分支是否已经被合并到远程分支时,您需要明确知道您要比较的是哪两个分支。 这些命令对于理解分支之间的关系非常有用,尤其是在处理复杂的合并和分支策略时。 git branch —merged