Skip to content

git常见问题处理

git基本操作

  1. Git push
  2. Git pull
  3. Git rebase
  4. Git meger
  5. git revert

https://www.atlassian.com/git/tutorials/syncing/git-push

分支的新建与合并

新建分支

首先,我们假设你正在你的项目上工作,并且在 master 分支上已经有了一些提交。

img

现在,你已经决定要解决你的公司使用的问题追踪系统中的 #53 问题。 想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b 参数的 git checkout 命令:

shell
$ git checkout -b iss53 

Switched to a new branch "iss53"

img

img

你继续在 #53 问题上工作,并且做了一些提交。 在此过程中,iss53 分支在不断的向前推进,因为你已经检出到该分支 (也就是说,你的 HEAD 指针指向了 iss53 分支)

shell
$ vim index.html
shell
$ git commit -a -m 'added a new footer [issue 53]'

img

img

img

有了 Git 的帮助,你不必把这个紧急问题和 iss53 的修改混在一起, 你也不需要花大力气来还原关于 53# 问题的修改,然后再添加关于这个紧急问题的修改,最后将这个修改提交到线上分支。 你所要做的仅仅是切换回 master 分支。

但是,在你这么做之前,要留意你的工作目录和暂存区里那些还没有被提交的修改, 它可能会和你即将检出的分支产生冲突从而阻止 Git 切换到该分支。 最好的方法是,在你切换分支之前,保持好一个干净的状态。 有一些方法可以绕过这个问题(即,暂存(stashing) 和 修补提交(commit amending)), 我们会在 贮藏与清理 中看到关于这两个命令的介绍。 现在,我们假设你已经把你的修改全部提交了,这时你可以切换回 master 分支了

shell
git checkout master

img

切换回主分支 ,你的工作目录和你在开始 #53 问题之前一模一样

请牢记:当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。

Git 会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样。

新建hotfix 分支

接下来,你要修复这个紧急问题。 我们来建立一个 hotfix 分支,在该分支上工作直到问题解决:

shell
$ git checkout -b hotfix 
Switched to a new branch 'hotfix'

img

img

shell
$ vim index.html 
$ git commit -a -m 'fixed the broken email address' 
[hotfix 1fb7853] fixed the broken email address  1 file changed, 2 insertions(+)

img

img

  • 切换回master 分支

基于 master 分支的紧急问题分支 hotfix branch

你可以运行你的测试,确保你的修改是正确的,然后将 hotfix 分支合并回你的 master 分支来部署到线上。 你可以使用 git merge 命令来达到上述目的:

shell
$ git checkout master 
$ git merge hotfix 
Updating f42c576..3a0874c 
Fast-forward  index.html | 2 ++  
1 file changed, 2 insertions(+)

img

  • 快进

在合并的时候,你应该注意到了“快进(fast-forward)”这个词。 由于你想要合并的分支 hotfix 所指向的提交 C4 是你所在的提交 C2 的直接后继, 因此 Git 会直接将指针向前移动。换句话说,当你试图合并两个分支时, 如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候, 只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。

现在,最新的修改已经在 master 分支所指向的提交快照中,你可以着手发布该修复了。

img

  • master 被快进到 hotfix

关于这个紧急问题的解决方案发布之后,你准备回到被打断之前时的工作中。 然而,你应该先删除 hotfix 分支,因为你已经不再需要它了 —— master 分支已经指向了同一个位置。 你可以使用带 -d 选项的 git branch 命令来删除分支:

shell
$ git branch -d hotfix 
Deleted branch hotfix (3a0874c).

img

现在你可以切换回你正在工作的分支继续你的工作,也就是针对 #53 问题的那个分支(iss53 分支)。

shell
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)

img

  • 继续在 iss53 分支上的工作

你在 hotfix 分支上所做的工作并没有包含到 iss53 分支中。 如果你需要拉取 hotfix 所做的修改,你可以使用 git merge master 命令将 master 分支合并入 iss53 分支,或者你也可以等到 iss53 分支完成其使命,再将其合并回 master 分支。

分支的合并

假设你已经修正了 #53 问题,并且打算将你的工作合并入 master 分支。 为此,你需要合并 iss53 分支到 master 分支,这和之前你合并 hotfix 分支所做的工作差不多。 你只需要检出到你想合并入的分支,然后运行 git merge 命令:

这和你之前合并 hotfix 分支的时候看起来有一点不一样。 在这种情况下,你的开发历史从一个更早的地方开始分叉开来(diverged)。 因为,master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4 和 C5)以及这两个分支的公共祖先(C2),做一个简单的三方合并。

img

  • 一次典型合并中所用到的三个快照

和之前将分支指针向前推进所不同的是,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。 这个被称作一次合并提交,它的特别之处在于他有不止一个父提交。

img

  • 一个合并提交

既然你的修改已经合并进来了,就不再需要 iss53 分支了。 现在你可以在任务追踪系统中关闭此项任务,并删除这个分支。

shell
$ git branch -d iss53

文件还原

$ git checkout -- index.html # 丢弃某个文件,或者
$ git checkout -- . # 丢弃全部
或者使用
$ git restore <file>

注意:

git checkout – . 丢弃全部,也包括:新增的文件会被删除、删除的文件会恢复回来、修改的文件会回去。这几个前提都说的是,回到暂存区之前的样子。对之前保存在暂存区里的代码不会有任何影响。对commit提交到本地分支的代码就更没影响了。当然,如果你之前压根都没有暂存或commit,那就是回到你上次pull下来的样子了。

当文件已经 add 之后无法恢复文件是 ,需要重置git add 操作

  • 撤销操作

img

img

撤销commit

shell
git reset --soft HEAD^

版本回退(之后版本将会没有记录)

shell
$ git reset --hard HEAD^  ## 强制回退到上一次add
$ git reset --head HEAD^^ ## 回退上上个版本

img

shell
$ git reset --hard HEAD^^  ## 回退上上个版本

img

shell
$ git reset --hard <hash> ##回退到特定版本

img

删除了 v5 ~ v2 版本 ,记录将不存在

回到旧版本(保留之前的版本)

shell
$ git checkout <CommitID> --  ##  回到与 hash 相同的版本 ,保留之前的版本

img

img

回滚提交

shell
$ git revert commitID  ##  回滚到commitID 提交

前端知识体系 · wcrane