Git:从容地丢掉无用分支而不失去提交的特殊技巧与两个提示

重要!本文说明的方法仅供娱乐。在实际生产过程中乱用所产生的后果由使用者自行承担。另外,不保证本文所述信息之准确性。

如果一个分支没有被合并到其他分支上,那么这个分支就不能被直接删除(git branch -d),必须强制删除(git branch -D)。然而强制删除会造成此分支上未合并的提交丢失在海洋中,显然这就不能让Git记录下版本库中发生的全部历史。一种解决方案如下:

  1. 打开(checkout)另一个(不用丢弃的)无用分支。可以选择比较干净的分支,例如gh-pages。如果没有,可以新建一个分支,此情况的备选命名有recycle-bin、rubbish、trash-can、garbage-collection(此名称不建议用在程序语言的项目版本库中)等。
    Y:\X>git co gh-pages
    Switched to branch 'gh-pages'
    Your branch is up-to-date with 'origin/gh-pages'.
  2. 试图将要丢弃的分支合并至此。(我可没说过不用合并。)合并时加上-X ours --no-commit参数。
    Y:\X>git merge -X ours --no-commit useless
    Automatic merge went well; stopped before committing as requested
  3. 利用你强大的技巧——不管是命令行还是编辑器——把新添加进来的文件删除。这步挺麻烦,我也没找到有什么好方法能简化操作。如果你上一步没有加--no-commit参数,Git会显示一份增量表(就像下面这样),照着那个来就行了。
    Y:\X>git merge -X ours useless
    Merge made by the 'recursive' strategy.
     *** |   3 +
     *** |   6 ++
     *** |   9 ++
     *** |  18 ++++
     *** |  27 ++++++
     *** |  27 ++++++
     *** |  36 ++++++++
     *** |  38 ++++++++
     *** |  39 ++++++++
     *** |  40 ++++++++
     *** |  42 +++++++++
     *** |  54 +++++++++++
     *** |  55 +++++++++++
     *** |  64 +++++++++++++
     *** |  65 +++++++++++++
     *** |  67 ++++++++++++++
     *** |  72 +++++++++++++++
     *** |  86 ++++++++++++++++++
     *** | 105 +++++++++++++++++++++
     *** | 125 +++++++++++++++++++++++++
     *** | 172 +++++++++++++++++++++++++++++++++++
     *** | 189 ++++++++++++++++++++++++++++++++++++++
     *** | 200 ++++++++++++++++++++++++++++++++++++++++
     *** | 201 +++++++++++++++++++++++++++++++++++++++++
     24 files changed, 1740 insertions(+)
     create mode 100644 ***
    …

    (数据截自真实案例#(滑稽),文件名被模糊)

    一切完成之后,git status的结果应该如下,其中最重要的是“工作目录干净如新”这一句。

    Y:\>git status
    On branch gh-pages
    Your branch is up-to-date with 'origin/gh-pages'.
    All conflicts fixed but you are still merging.
      (use "git commit" to conclude merge)
    
    nothing to commit, working directory clean
  4. git commit!还记得上一条中git status萌萌地说了一句“nothing to commit”吗?但是这根本不妨碍我们提交。
    Y:\X>git commit -m "I made it! Yay!"
    [gh-pages 29cf732] Merge branch 'useless' into gh-pages
  5. 正常删除要丢掉的分支。Git会很高兴。
    Y:\X>git branch -d useless
    Deleted branch useless (was e9b464f).

提示一:不想删除而是想把它拖离到其他地方?先找到目的地的提交哈希值,然后直接写进.git/refs/heads/useless里。这时候Git会一脸懵逼,然后觉得你的工作目录怎么这么脏啊,重置即可。之后就能动用git push -f这种大招数把远端库也更新了。

提示二:不小心改乱了工作目录?再也不用记住执行git checkout还是git reset,你只需要一个命令:git stash。这种情况下,Git提供的储藏间就是你的垃圾桶。这种方法针对提示一中工作目录的情况特别有效。

你可以随时通过git stash clear来清空储藏间(垃圾桶)。

顺带一提,这篇文章直接导致了IcebergOS/Cryst里的这个提交。我认为,我提交完是这个样子的,你提交完也应该是这个样子的。

发表评论

电子邮件地址不会被公开。 必填项已用*标注