Merge pull request #21465 from lujun9972/add-MjAyMTAzMzEgMyByZWFzb25zIEkgdXNlIHRoZSBHaXQgY2hlcnJ5LXBpY2sgY29tbWFuZC5tZAo=

自动选题[tech]: 20210331 3 reasons I use the Git cherry-pick command
This commit is contained in:
Xingyu.Wang 2021-04-01 07:56:21 +08:00 committed by GitHub
commit 46fb596bfa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -0,0 +1,198 @@
[#]: subject: (3 reasons I use the Git cherry-pick command)
[#]: via: (https://opensource.com/article/21/3/git-cherry-pick)
[#]: author: (Manaswini Das https://opensource.com/users/manaswinidas)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
3 reasons I use the Git cherry-pick command
======
Cherry-picking solves a lot of problems in Git repositories. Here are
three ways to fix your mistakes with git cherry-pick.
![Measuring and baking a cherry pie recipe][1]
Finding your way around a version control system can be tricky. It can be massively overwhelming for a newbie, but being well-versed with the terminology and the basics of a version control system like Git is one of the baby steps to start contributing to open source.
Being familiar with Git can also help you out of sticky situations in your open source journey. Git is powerful and makes you feel in control—there is not a single way in which you cannot revert to a working version.
Here is an example to help you understand the importance of cherry-picking. Suppose you have made several commits in a branch, but you realize it's the wrong branch! What do you do now? Either you repeat all your changes in the correct branch and make a fresh commit, or you merge the branch into the correct branch. Wait, the former is too tedious, and you may not want to do the latter. So, is there a way? Yes, Git's got you covered. Here is where cherry-picking comes into play. As the term suggests, you can use it to hand-pick a commit from one branch and transfer it into another branch.
There are various reasons to use cherry-picking. Here are three of them.
### Avoid redundancy of efforts
There's no need to redo the same changes in a different branch when you can just copy the same commits to the other branch. Please note that cherry-picking commits will create a fresh commit with a new hash in the other branch, so please don't be confused if you see a different commit hash.
In case you are wondering what a commit hash is and how it is generated, here is a note to help you: A commit hash is a string generated using the [SHA-1][2] algorithm. The SHA-1 algorithm takes an input and outputs a unique 40-character hash. If you are on a [POSIX][3] system, try running this in your terminal:
```
`$ echo -n "commit" | openssl sha1`
```
This outputs a unique 40-character hash, `4015b57a143aec5156fd1444a017a32137a3fd0f`. This hash represents the string `commit`.
A SHA-1 hash generated by Git when you make a commit represents much more than just a single string. It represents:
```
sha1(
    meta data
        commit message
        committer
        commit date
        author
        authoring date
    Hash of the entire tree object
)
```
This explains why you get a unique commit hash for the slightest change you make to your code. Not even a single change goes unnoticed. This is because Git has integrity.
### Undoing/restoring lost changes
Cherry-picking can be handy when you want to restore to a working version. When multiple developers are working on the same codebase, it is very likely for changes to get lost and the latest version to move to a stale or non-working version. That's where cherry-picking commits to the working version can be a savior.
#### How does it work?
Suppose there are two branches, `feature1` and `feature2`, and you want to apply commits from `feature1` to `feature2`.
On the `feature1` branch, run a `git log` command, and copy the commit hash that you want to cherry-pick. You can see a series of commits resembling the code sample below. The alphanumeric code following "commit" is the commit hash that you need to copy. You may choose to copy the first six characters (`966cf3` in this example) for the sake of convenience:
```
commit 966cf3d08b09a2da3f2f58c0818baa37184c9778 (HEAD -> master)
Author: manaswinidas <[me@example.com][4]>
Date:   Mon Mar 8 09:20:21 2021 +1300
   add instructions
```
Then switch to `feature2` and run `git cherry-pick` on the hash you just got from the log:
```
$ git checkout feature2
$ git cherry-pick 966cf3.
```
If the branch doesn't exist, use `git checkout -b feature2` to create it.
Here's a catch: You may encounter the situation below:
```
$ git cherry-pick 966cf3
On branch feature2
You are currently cherry-picking commit 966cf3d.
nothing to commit, working tree clean
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:
   git commit --allow-empty
Otherwise, please use 'git reset'
```
Do not panic. Just run `git commit --allow-empty` as suggested:
```
$ git commit --allow-empty
[feature2 afb6fcb] add instructions
Date: Mon Mar 8 09:20:21 2021 +1300
```
This opens your default editor and allows you to edit the commit message. It's acceptable to save the existing message if you have nothing to add.
There you go; you did your first cherry-pick. As discussed above, if you run a `git log` on branch `feature2`, you will see a different commit hash. Here is an example:
```
commit afb6fcb87083c8f41089cad58deb97a5380cb2c2 (HEAD -> feature2)
Author: manaswinidas <[me@example.com][4]>
Date:   Mon Mar 8 09:20:21 2021 +1300
   add instructions
```
Don't be confused about the different commit hash. That just distinguishes between the commits in `feature1` and `feature2`.
### Cherry-pick multiple commits
But what if you want to cherry-pick multiple commits? You can use:
```
`git cherry-pick <commit-hash1> <commit-hash2>... <commit-hashn>`
```
Please note that you don't have to use the entire commit hash; you can use the first five or six characters.
Again, this is tedious. What if the commits you want to cherry-pick are a range of continuous commits? This approach is too much work. Don't worry; there's an easier way.
Assume that you have two branches:
* `feature1` includes commits you want to copy (from `commitA` (older) to `commitB`).
* `feature2` is the branch you want the commits to be transferred to from `feature1`.
Then:
1. Enter `git checkout <feature1>`.
2. Get the hashes of `commitA` and `commitB`.
3. Enter `git checkout <branchB>`.
4. Enter `git cherry-pick <commitA>^..<commitB>` (please note that this includes `commitA` and `commitB`).
5. Should you encounter a merge conflict, [solve it as usual][5] and then type `git cherry-pick --continue` to resume the cherry-pick process.
### Important cherry-pick options
Here are some useful options from the [Git documentation][6] that you can use with the `cherry-pick` command:
* `-e`, `--edit`: With this option, `git cherry-pick` lets you edit the commit message prior to committing.
* `-s`, `--signoff`: Add a "Signed-off-by" line at the end of the commit message. See the signoff option in git-commit(1) for more information.
* `-S[<keyid>]`, `--gpg-sign[=<keyid>]`: These are GPG-sign commits. The `keyid` argument is optional and defaults to the committer identity; if specified, it must be stuck to the option without a space.
* `--ff`: If the current HEAD is the same as the parent of the cherry-picked commit, then a fast-forward to this commit will be performed.
Here are some other sequencer subcommands (apart from continue):
* `--quit`: You can forget about the current operation in progress. This can be used to clear the sequencer state after a failed cherry-pick or revert.
* `--abort`: Cancel the operation and return to the presequence state.
Here are some examples of cherry-picking:
* `git cherry-pick master`: Applies the change introduced by the commit at the tip of the master branch and creates a new commit with this change
* `git cherry-pick master~4 master~2`: Applies the changes introduced by the fifth and third-last commits pointed to by master and creates two new commits with these changes
Feeling overwhelmed? You needn't remember all the commands. You can always type `git cherry-pick --help` in your terminal to look at more options or help.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/git-cherry-pick
作者:[Manaswini Das][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/manaswinidas
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/pictures/cherry-picking-recipe-baking-cooking.jpg?itok=XVwse6hw (Measuring and baking a cherry pie recipe)
[2]: https://en.wikipedia.org/wiki/SHA-1
[3]: https://opensource.com/article/19/7/what-posix-richard-stallman-explains
[4]: mailto:me@example.com
[5]: https://opensource.com/article/20/4/git-merge-conflict
[6]: https://git-scm.com/docs/git-cherry-pick