git 使用笔记

本文档主要记录 git 平常高频使用命令。git

本地仓库由 git 维护的三棵“树”组成。
第一个是工做目录,它持有实际文件;
第二个是暂存区(Index),它像个缓存区域,临时保存改动;
最后是 HEAD,它指向你最后一次提交的结果。
以下图所示,shell

新建

  1. git init,建立一个新的本地仓库。
  2. git clone -b <远端分支名> <url> <local-name>,从远端 url 拉取仓库拉取制定分支到本地 local-name 文件夹下,若是不加远端分支名,则为默认分支 master。

提交

  1. git add <file1> <file2> ... 将 working dir 相应文件的更改提交到 index 中。
  2. git add . 提交全部文件的更改。
  3. git commit -m 'cmmit xx' 将 index 中的内容提交到本地仓库,HEAD 指向最新提交。
  4. git commit -a -m 'commit xx' 将 working dir 全部更改一次性提交到本地仓库。
  5. git commmit 做用同 3,可是会弹出窗口,支持更长的 commit 信息。
  6. git push <上游> <上游分支> 代码提交到远端库。

commit 信息变动

  1. git commit --amend 进入编辑器,修改上一次的 commit 信息。
  2. 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

撤销

  1. git checkout -- <file> 撤销一个工做区文件(必须是已经被 track 的文件)的修改。<file> 参数为 . 时表示撤销全部修改。
  2. git rm --cached <file> 从 index 中删除一个文件,使之变为 Untracked files 状态。
  3. git reset HEAD <file> 从 index 中撤销一个更改。
  4. git reset --soft <commitid> 从本地仓库 HEAD 回滚到 index 区(未 commit 的状态)。
  5. git reset --mixed <commitid> 从本地仓库 HEAD 回滚到工做区(未 add 的状态)。
  6. git reset --hard <commitid> 从本地仓库 HEAD 作版本回退(工做区未更改,已提交)。
  7. git revert --no-commit <commit1>..<commit2> 撤销指定 cimmit 的代码提交。
    撤销从 commit1 到 commit2 的提交,区间前开后闭区间。--no-commit 表示能够最后一块儿手动 git commit 提交。
    revert 实际上是将要取消的提交记录按照相反的操做将他们抵消掉,而后从新生成一个提交记录,这样在提交记录的完整性上更好,不一样于 reset 的直接抹掉。
    有冲突时须要手动修复,add 后再次 continue。
  8. git merge --abort 抛弃合并过程而且尝试重建合并前的状态。该命令仅仅在合并后致使冲突时才使用

分支管理

  1. git checkout -b <banch name> <base branch> 基于 base 分支建立一个新分支,并切到新分支。base 分支为空时,表示为当前分支,base 分支若是为远端分支,则要加上游分支名字,如 origin/dev
  2. git checkout <branch name> 切到某分支。
  3. git branch -a 查看全部分支。

代码 diff

  1. git diff <commit1> <commit2> <filename> 比较 file 在两个版本以前的差别。
    若是不加 filename,那么比较全部文件的差别,
    若是只有一个 commitid,表示指定 commitid 与当前版本的差别。
    若是没有 commitid,只有 filename,比较某个文件与 HEAD 中的差别。
    若是后面什么参数也没有,表示与 HEAD 的全部差别。
  2. git diff --staged/--cached 比较暂存区/工做区与上一次提交的差别。

删除文件/分支

  1. git branch -d <branch name> 删除本地分支。
  2. git push origin --delete <branch name> 删除远端分支。
  3. git rm --cached <file> 并进行提交,完成本地文件在远端的删除。

代码合并

  1. git merge <feature> <master> 在 feature 上合并 master(这可能出现冲突,须要自行解决),
    若是参数只有一个 branch,则表示与当前分支合并。

    feature 分支每次须要合并上游更改时,它都将产生一个额外的合并提交。若是master 提交很是活跃,这可能会严重污染你的 feature 分支历史记录spa

  2. git rebase -i <branch name> 交互式合并指定分支。

rebase 经过为原始分支中的每一个提交建立全新的 commits 来 重写 项目历史记录。
rebase 的主要好处是能够得到更清晰的项目历史。
在提交拉取请求以前,一般使用交互式 rebase 清理代码一般是个好的办法,可是在别人使用的分支(公共分支)上进行 rebase,重写其历史记录将使 Git 和你的队友没法跟踪添加到该功能的任何后续提交,也会在别人拉取代码时产生冲突
在你运行 git rebase 命令以前,老是问本身,还有其余人在用这个分支吗? 若是答案是确定的,那就把你的手从键盘上移开,开始考虑采用非破坏性的方式进行改变(例如,git merge 命令)。不然,你能够为所欲为地重写历史记录。3d

  1. 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 这种方式。

相关文章
相关标签/搜索