本文档主要记录 git 平常高频使用命令。git
本地仓库由 git 维护的三棵“树”组成。
第一个是工做目录,它持有实际文件;
第二个是暂存区(Index),它像个缓存区域,临时保存改动;
最后是 HEAD,它指向你最后一次提交的结果。
以下图所示,shell
git init
,建立一个新的本地仓库。git clone -b <远端分支名> <url> <local-name>
,从远端 url 拉取仓库拉取制定分支到本地 local-name 文件夹下,若是不加远端分支名,则为默认分支 master。git add <file1> <file2> ...
将 working dir 相应文件的更改提交到 index 中。git add .
提交全部文件的更改。git commit -m 'cmmit xx'
将 index 中的内容提交到本地仓库,HEAD 指向最新提交。git commit -a -m 'commit xx'
将 working dir 全部更改一次性提交到本地仓库。git commmit
做用同 3,可是会弹出窗口,支持更长的 commit 信息。git push <上游> <上游分支>
代码提交到远端库。git commit --amend
进入编辑器,修改上一次的 commit 信息。git rebase -i <commitid>
合并 commit。举例说明,使用 git log
查看,有如下 4 个 commit,缓存
commit C4 Date: Sun Jun 21 17:25:56 2020 +0800 add line11 commit C3 Date: Sun Jun 21 17:24:33 2020 +0800 add line10 commit C2 Date: Sun Jun 21 11:49:06 2020 +0800 add line1 commbine 1 commit C1 Date: Sun Jun 21 11:45:06 2020 +0800 add newfile
如今,我想要将 C2 和 C3 合并,那么找到最先的 commit C2 的上一个 C1(或者使用 C2^
),执行 git rebase -i C1
,会出现合并 commit 选择的页面,大概以下,编辑器
pick C2 add line1 pick C3 add line10 pick C4 add line11 # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit
根据命令说明,将要合并的 commit 前面的命令改为 f
或者 s
, 二者的区别的是 f
在编辑合并后 commit的信息时只会出现最后一条,而 s
都会保存,建议使用 s
。要合并 C2 和 C3 的话,那么选择时间早的 C2,因此把 C3 前的 pick
改成 s
,保存。post
接着会出现编辑页,编辑合并后 commit 的提交信息,改好之后再次保存就可。this
注意:要合并的 C2 和 C3 是连续的 commit。url
git checkout -- <file>
撤销一个工做区文件(必须是已经被 track 的文件)的修改。<file>
参数为 .
时表示撤销全部修改。git rm --cached <file>
从 index 中删除一个文件,使之变为 Untracked files 状态。git reset HEAD <file>
从 index 中撤销一个更改。git reset --soft <commitid>
从本地仓库 HEAD 回滚到 index 区(未 commit 的状态)。git reset --mixed <commitid>
从本地仓库 HEAD 回滚到工做区(未 add 的状态)。git reset --hard <commitid>
从本地仓库 HEAD 作版本回退(工做区未更改,已提交)。git revert --no-commit <commit1>..<commit2>
撤销指定 cimmit 的代码提交。--no-commit
表示能够最后一块儿手动 git commit 提交。git merge --abort
抛弃合并过程而且尝试重建合并前的状态。该命令仅仅在合并后致使冲突时才使用。git checkout -b <banch name> <base branch>
基于 base 分支建立一个新分支,并切到新分支。base 分支为空时,表示为当前分支,base 分支若是为远端分支,则要加上游分支名字,如 origin/dev
。git checkout <branch name>
切到某分支。git branch -a
查看全部分支。git diff <commit1> <commit2> <filename>
比较 file 在两个版本以前的差别。git diff --staged/--cached
比较暂存区/工做区与上一次提交的差别。git branch -d <branch name>
删除本地分支。git push origin --delete <branch name>
删除远端分支。git rm --cached <file>
并进行提交,完成本地文件在远端的删除。git merge <feature> <master>
在 feature 上合并 master(这可能出现冲突,须要自行解决),feature 分支每次须要合并上游更改时,它都将产生一个额外的合并提交。若是master 提交很是活跃,这可能会严重污染你的 feature 分支历史记录。spa
git rebase -i <branch name>
交互式合并指定分支。rebase 经过为原始分支中的每一个提交建立全新的 commits 来 重写 项目历史记录。
rebase 的主要好处是能够得到更清晰的项目历史。
在提交拉取请求以前,一般使用交互式 rebase 清理代码一般是个好的办法,可是在别人使用的分支(公共分支)上进行 rebase,重写其历史记录将使 Git 和你的队友没法跟踪添加到该功能的任何后续提交,也会在别人拉取代码时产生冲突。
在你运行 git rebase
命令以前,老是问本身,还有其余人在用这个分支吗? 若是答案是确定的,那就把你的手从键盘上移开,开始考虑采用非破坏性的方式进行改变(例如,git merge
命令)。不然,你能够为所欲为地重写历史记录。3d
git cherry-pick <commitid1>..<commitid2>
从 commitid1(不包括)到 commitid2 的更改,应用到本分支,若是要包含 commitid1,则使用 commitid1^
永远不要在公共分支上使用 git rebase
。
在私人分支,rebase 修改我的本次功能的 commit,经过按期执行交互式 rebase,你能够确保功能中的每一个提交都具备针对性和意义。而后 merge 到主分支上。rest
更多参考 《git rebase VS git merge? 更优雅的 git 合并方式值得拥有》
git pull <上游> <上游分支>
从上游拉取指定分支。
若是上游分支与本地分支存在交叉,就会出现 Merge branch 'xx' of xx into xxx 的自动 commit,因此最好在使用 git pull
命令时,后面加上 --rebase
选项。
若是拉取不产生冲突,会直接 rebase,不会产生分支合并操做,若是有冲突则须要手动 fix 后,自行合并。
注意:以上全部使用 commitid 的地方,也均可以使用 HEAD/ HEAD^/HEAD~3 这种方式。