翻译进度
10
分块数量
2
参与人数

使用 Git rebase 来整理 Git 提交历史

这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。


这篇文章的目标读者是那些想学习如何使用诸如 rebase 之类的命令并学习一些技巧以获得更好的 Git 体验的人。

好了,让我们先从我在 Github 上的第一个项目的 Git 历史开始观看:

git history 01

这样不好

git history 02

这样也不好

git history 03

我的天,我到底做了什么

自嘲过后, 现在我们来看看我的大多数项目是什么样的 😄

git history 04

哎呀,好多了

likunyan 翻译于 1个月前

如果您不知道这一切意味着什么,请让我简要说明一下:

这代表了您在 Github 上的 Git 历史,意思就是随着时间的推移您在项目分支上所做的提交。

您可以通过导航到您的一个 GitHub 项目的 Insights 选项卡,然后点击左侧的 Network 选项卡来查看自己的内容。

黑色栏代表主分支 master,蓝色和绿色交替交替代表独立的分支。

如您所见,在最近的更好的历史记录中,它们交替地合并到 master 中,从而创建了编写和合并代码的良好流程(始终建议这样做,而不是累积 pull 请求)。

那么,如何才能拥有更简洁的历史记录呢? 让我们来看一下实际的用例。

git rebase 的魔力

官方文档

Git rebase 使您可以根据自己的意愿重塑 Git 历史。 将其视为一种处理给定分支上的提交列表的方法。

例如,您可以完全删除提交(基本上是对 Git 历史深渊说再见),对其进行重命名(重写您的提交消息),将它们合并为另外的提交(这对于隐藏小改变的提交很有用,例如添加一个分号,您真的不想在历史记录中看到它们)以及更多其他内容。

likunyan 翻译于 1个月前

Learning by practice

Go to the following project I made for the occasion, fork it and let's get started.

Forking is basically creating a copy of my project for yourself, you'll be able to mess around with it without any problems ! To do it, click on the fork button on the top right:

fork button

Then, clone the repository you forked.

Example 1: fixing up a commit with rebase

Scenario: you have committed something that does not deserve a commit of its own, or you want to reduce the number of commits on your branch to one before making a pull request.

  • From the master branch, create a new branch.

  • Create a new file, its content doesn't really matter.

  • Commit that new file to your branch.\

git add index.js
git commit -m "add index.js"
  • Update something in that file

  • Commit it again with a message such as "update index.js"

  • Run git log, as you can see, we now have 2 commits

We now want to fixup the update commit into the add commit, because this small change does not deserve a commit of its own.

To do so, we'll use the interactive mode of git rebase, which lets us apply the rebasing with a nice interface.

  • Run the rebase command like so:
git rebase -i HEAD~2

HEAD~2 means start from the last commit on the branch (the head) and go back 2 commits. If we wanted to manipulate more commits, we could change the value to the far right.\
\
You should now have an interface that looks something like this:

rebase interactive

Don't panic, this only shows you the two commits you are changing at the top, and the available commands bellow them.\

By default, the rebase interface uses Vim, to write in it, simply press the i key. You are now in "INSERT" mode. As we want to fixup the second commit in the first one, all we have to do is write fixup or f instead of pick in front of it. Our update index.js commit will now be squashed into the add index.js but only the add index.js's message will be kept.

  • Update the second line like so:
pick c0091ec add index.js
f a19336e update index.js

Now, we want to apply the rebase, press escape to leave the INSERT mode, press : (colon) and enter wq for "write" and "quit" and press ENTER to apply these changes. The colon simply allows you to write commands for Vim to execute.

The following message should now appear in your console:

Successfully rebased and updated refs/heads/{YOUR BRANCH NAME}.

Check your git log, you now have one beautiful and clean commit !

  • Finally, force push to that branch to apply the rebase to the remote server
git push origin {BRANCH-NAME} -f

The -f is essential as a rebase modifies your git history and requires to be forced.

Example 2: dropping a commit

These next 2 steps will be extremely similar to the first one because you now have the tools to do any kind of rebasing 🎉

Scenario: you want to completely remove a commit

We'll drop the add FILENAME commit we previously made:

  • Run the rebase command
git rebase -i HEAD~1
  • Add a d or drop in front of the commit you wish to drop.

rebase drop

  • Run :wq in your Vim editor (and check with git log that the commit was dropped)

  • Don't forget to force push it to your remote server 😀

Example 3: rewording a commit

Pretty similar, with one change.

Scenario: you want to fix a typo or rewrite a commit's title or description

  • Create a random commit

git reword

  • Run the rebase command
git rebase -i HEAD~1
  • Add a r or reword in front of the commit you wish to reword (no need to edit the title now).

  • Run :wq in your Vim editor. This will open a similar editor with the commit(s) you wish to reword.

git reword 2

  • Update the commit's title and description to your will, run :wq and that's it ! Check with git log that the rewording was applied

git reword 3

  • Don't forget to force push it to your remote server 😀

Example 4: rebasing on master

This example isn't reproduced in the Github project, but feel free to test it out.

Scenario: you have multiple PRs (Pull Requests) open at the same time

rebase master screenshot

You merge one PR, now, your second PR is not up to date with master, oh no !

rebase master screenshot 2

This very frequent scenario will have us rebase our second PR on master so that it gets the new code merged from the first PR.

  • From the branch you want to rebase (in our case, the second PR's branch), run the following:
git fetch

This downloads all the references our branch needs to apply the rebase.

  • Then, execute the rebase like so:
git rebase origin/master
  • Finally, run a git push origin {MY-BRANCH} -f to apply the rebase to our remote server

rebase master screenshot 3

Hurray !

Bonus: a better git log

Is your git log too much to handle?

git log screenshot

Would you rather have a git log that is straight to the point and looks nicer?

git log screenshot 2

Look no further ! Here's how you can achieve it, in your console, paste the following:\

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

You've now created an alias to git log called git lg that will display the nicer output showed before. Try it out by typing git lg (or git lg -p to see the lines that have changed).

On the dangers of force pushing & other things to note

Force pushing can be dangerous when working with a team as mentioned by Nick Huanca:

So another alternative may be --force-with-lease which "allows one to force push without the risk of unintentionally overwriting someone else’s work. It will update remote references only if it has the same value as the remote-tracking branch we have locally." Reference. Thanks for the tip Nick ! 😄

As you may have noted he also mentions git rebase --abort, which allows us to stop a rebasing mid-way through in case anything goes wrong. So if for any reason you mess up your rebase, git it a little --abort and start again.

Closing thoughts

Learning how to use Git is probably one of the most important skills we can acquire as developers. I hope some of you won't be as afraid of rebase as I was a while ago.

本文章首发在 LearnKu.com 网站上。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://dev.to/christopherkade/up-your-g...

译文地址:https://learnku.com/devtools/t/37980

参与译者:2
讨论数量: 1
likunyan

让我们一起变基吧

Git

1个月前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!