Git: Is there any way to find out where the check came from?

If I have a cherry pick from several branches, is there an easy way to find out where the commit came from (e.g. sha initial commit)?

Example:
- in the master branch
- grab cherry A from the dev branch
- A becomes D on the main branch

Before:

* B (master) Feature Y | * C (dev) Feature Z | * A Feature X |/ * 3 * 2 * 1 

After:

 * D (master) Feature X * B Feature Y | * C (dev) Feature Z | * A Feature X |/ * 3 * 2 * 1 

Is it possible to calculate that D selected a cherry from A (other than searching for a commit message)?

Edit:
Although I will go with rags (see VonCs Answer), I received Chris Johnsen because he is closer to the real question. Thanks guys.

+27
git version-control
May 27 '10 at 15:51
source share
3 answers

By default, information about the original cherry commit is not recorded as part of the new commit.

Record source commit in ad

If you can force the use of certain workflows / options, git cherry-pick has the -x option:

When recording a commit, add a note to the original commit message indicating which of these changes was selected from the cherry.

This is obviously useless if you cannot rely on cherry pickers using this option. Also, since the recorded information is plain text and not the actual link to Git, even if you use -x , you still need to take steps to make sure the original commit is saved (for example, is part of a DAG tag or branch without rewinding )

git cherry and git patch-id

If you can limit your search to two separate branches of the DAG history, then git cherry can find both "unpicked" and "selected" cherries.

Note This command (and its associated git patch identifier ) can only identify conflicting cherries that were individually selected without further changes. If there is a conflict when you select a cherry (for example, you needed to slightly change it to make it apply), or you used -n / --no-commit to make additional changes (for example, several cherries in one commit) or the contents of the commit were rewritten after selection, then you would have to rely on comparing commit messages (or -x information if it was written).

git Cherry is not intended to determine the origin of the collected cherries, but we can use it a little to identify individual cherry pairs.

Given the following DAG story (as in the example with the original posters):

 1---2---3---B---D master \ A---C dev # D is a cherry-picked version of C 

you will see something like this:

 % git cherry master dev + A - C % git cherry dev master + B - D 

(A, B, C, and D are full SHA-1 hashes in real output)

Since in each list we see one cherry (lines - ), they should form a cherry pair. D was a cherry selected from C (or vice versa, you cannot tell only with DAG, although commit dates may help).

If you are dealing with more than one potential cherry, you will need to “minimize your” program to make a comparison. The code should be simple in any language with associative arrays, hashes, dictionaries, or equivalent. In awk, it might look like this:

 match_cherries() { a="$(git rev-parse --verify "$1")" && b="$(git rev-parse --verify "$2")" && git rev-list "$a...$b" | xargs git show | git patch-id | awk ' { p[$1] = p[$1] " " $2 } END { for (i in p) { l=length(p[i]) if (l>41) print substr(p[i],2,l-1) } }' } match_cherries master dev 

In an extended example, in which there are two collected cherries:

 1---2---3---B---D---E master \ A---C dev # D is a cherry-picked version of C # E is a cherry-picked version of A 

The result may look like this:

 match_cherries master dev DC EA 

(A, C, D, and E are full SHA-1 hashes in real output)

This tells us that C and D represent the same change and that E and A represent the same change. As before, there is no way to determine which of each pair was “first” if you do not take into account (for example) the fixation dates of each commit.

Control Message Comparison

If your cherries were not selected with -x , or they are dirty (had conflicts or other changes added to them (i.e. using --no-commit plus additional changes or using git commit --amend or another “rewriting history”)), then you may have to abandon a less reliable method for comparing commit messages.

This method works best if you can find a commit message bit that is likely to be unique to the commit, and is unlikely to change in the commit resulting from the cherry pick. The bit that will work best will depend on the style of commit messages used in your project.

Once you have chosen the "identification part" of the message, you can use git log to find commits (also shown in Jeffries' Answer).

 git log --grep='unique part of the commit message' dev...master 

The --grep argument is actually a regular expression, so you may need to avoid any regular expression metacharacters ( []*?.\ ).

If you are not sure which branches might contain the original commit and the new commit, you can use --all , as Jefromi showed.

+30
May 30 '10 at 6:09 a.m.
source share

If I follow your diagram, you want to know if you can determine what D (not B) is from the collection of cherry A.

In theory, as shown in “ How to list the git branches that contain a given commit? ”, You can look for a commit if D is actually the same commit (SHA1) as A:

 git branch --contains <commit> 

But as a Jefromi comment, D cannot have the same SHA1 in this case.
This leaves the search for a general commit message: see Jefromi's answer .




As Ken Bloom mentions in the comments of the question, for such a local set of cherries, the scrambling method (as in monotone or mercurial ) is more appropriate since it will leave a clear trace of merging.

Duggy corrections mean using instead of losing the true origin and connection between errors and corrections in the ancestral graph.

Since [Git] offers the ability to commit on top of any revision, thereby creating a tiny anonymous branch, a viable alternative to cherry picking is as follows:

  • use bisect to determine the version in which the error occurred;
  • Check this revision
  • correct the error;
  • and commit the fix as a child of the revision that introduced the error.

This new change can be easily merged into any branch that had the original error, without any fragmentary worms. It uses the normal merge and permission management tool to control versions, so it’s much more reliable than choosing a cherry (the implementation of which is almost always a series of grotesque hacks).

https://storage.googleapis.com/google-code-attachments/rainforce/issue -4 / comment-5 / Hg-dag-6-daggy-fix.png Hg DaggyFox

(here's a Mercury chart, but it's easy to apply to Git)

Performing fatigue corrections all the time is not for everyone.
It is not always so easy to develop a correction directly against the revision where the error was introduced.

  • Perhaps the error was not detected until some other later code used it in ways that displayed the error; it would be difficult to debug and find a fix without this other code.
  • Or perhaps the importance or scope of the fix was simply not implemented at that time.



See also this article for more information on daggy-fix :

This way of returning to history to correct a mistake, and then combine the correction into modern branches, was called the "bowel movement" of the authors Monotone , an influential distributed version control system.
The fixes are called daggy because they use the project history, which is structured as a directed acyclic graph or dag .
Although this approach can be used with Subversion, its branches are heavier than distributed tools, making the daggy-fix method less practical. This underlines the idea that the strengths of the tool will inform about the methods that its users bring.

+10
May 27 '10 at 10:18
source share

No information about the original commit is embedded in the newly created commit, so there is no direct way to tell. What you are suggesting (looking for a commit message) is probably the best way - it is certainly much easier than finding a commit with the same diff:

 git log --grep="<commit subject>" --all 

If, of course, the commit is no longer available from the branch ... maybe then you might want to see the result of git fsck .

+3
May 27 '10 at 23:59
source share



All Articles