可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've used git-blame to find a particular commit. Now I want to find the branch that it originally came from. (From there, I'll use the branch name to find the particular ticket)
Let's define "original branch" as "the branch to which the commit was made before the branch was merged into any other branch".
回答1:
Like the others said, if the branch you are looking for isn't local to the repository on which you are blaming this commit (e.g. a branch only in the personal repo of a distant developer), you are screwed.
But assuming that sought-after branch is something you can see, and that of course you have the commit's hash, say d590f2...
, a partial answer is that you can do :
$ git branch --contains d590f2
tests
* master
Then, just to confirm you have the culprit:
$ git rev-list tests | grep d590f2
Of course, if d590f2
has been merged in more than one branch, you will have to be more subtle than this.
回答2:
That isn't really applicable in git. Branches are local concepts to each repository: one person's "local-stuff" branch can be quite separate from another person's "local-stuff" branch. If you do something like looking at your main integration branch, and your query commit, and removing all the merge bases between the two, you should be able to get a subtree of the commit history that may shed some illumination... or may not. e.g. if you trace up the link from the query commit towards "master" you should hopefully find merge commits with useful comments saying where the merge came from... but this information is just informational, not recorded in some way intended to be automatically retrieved.
e.g. gitk some-commit...master
(which is almost short for gitk some-commit master --not $(git merge-base some-commit master)
)
回答3:
A Git branch is nothing else than a "named pointer to a commit" (that's a fundamental different concept than in other well-known VCS).
This situation is clear, commit A is on branch-1
, commit B on branch-2
:
o A [branch-1]
|
o | B [branch-2]
| |
After merging is becomes unclear whether A (or B) originally was on branch-1
or branch-2
:
o [branch-1] [branch-2]
|
o merged
|\
| o A
| |
o | B
| |
Maybe you can guess on what Git branch the commit A was if you have tagged parent commits of A, e.g. release-1
and you know that this tag only was given for commits in branch-1
.
o [branch-1] [branch-2]
|
o merged
|\
| o A
| |
o | B
| |
| o <release-1]
| |
回答4:
I give a try, please comment since not totally sure, but I believe it does the job.
The following will work only if the branches still point at the tip of before being merged into master, which is the case if the branches were on the same repo:
o [master]
|
o merged branch "great-feature" into master
|\
| o A [great-feature]
| |
o | B
| |
If it it not the case (for example if you pulled from another repo) you can still recreate them by hand.
First get the branches where your commit are:
$ git branch -a --contains=<sha-of-B>
*master
great-feature
then for each branch get the number of commits that separate their head to the commit: this is the number of lines that output git log for the specified range:
$ git log --pretty=oneline <sha-of-B>..great-feature | wc -l
1
$ git log --pretty=oneline <sha-of-B>..master | wc -l
4
So B is nearest to great-feature, which means it was created in it.
This could be made into a nice script, feel free to add it to the answer (I'm not good at this)
回答5:
First ensure you fetched changes from remotes
$ git fetch --all
And,
$ git branch -a --contains d590f2
Without -a option you can't find commits existing only on remote branches
回答6:
I found a simpler way to do it: it's in the message of the last commit of git log <sha>..HEAD --merges
!
This command shows the merges that have happened between master and the commit; the last commit output by this command is the first merge commit that included it. It usually contains the branch name, so even if the branch was deleted you can find its name.
To get only the name of the branch just type git log <sha>..HEAD --merges --oneline |tail -1
回答7:
It seems like this isn't a question that's possible to answer with 100% precision via git.
git branch --contains --merge <sha1>
returns a list of all branches to which the commit was merge and the original branch. --no-merged returns all subsequent branches that include the commit because they branched after the merge point.
So, you can get a list of each merge but not original branch and any branch deleted prior to command execution is lost (or your looking at reflogs)
Results
git branch --contains <sha1 for "added feature/inital 1">
* develop
feature/inital
feature/subsequent1
git branch --contains <sha1 for "added feature/inital 1"> --merged
* develop
feature/inital
git branch --contains <sha1 for "added feature/inital 1"> --no-merged
feature/inital
Test Script
function mkbranch {
git checkout -b $1
git push --set-upstream origin $1
}
# Develop
mkbranch develop
for f in 1 2 3; do date > file${f}.txt; git add file${f}.txt; git commit -m "added develop $f"; done
git push
# Initial Feature Branch
mkbranch feature/inital
for f in 1 3; do date > file${f}.txt; git add file${f}.txt; git commit -m "modified feature/inital $f"; done
git push
# Merge
git checkout -b develop
git merge feature/inital
git push
# Next Feature Branch
mkbranch feature/subsequent1
for f in 1 3; do date > file${f}.txt; git add file${f}.txt; git commit -m "modified feature/subsequent1 $f"; done
git push
回答8:
When you on the branch the "original branch" was merged to. You may run:
git log <SHA>..HEAD --ancestry-path --merges
This command will show all merge
commits between <SHA>..HEAD
. You need last one.
For example for c0118fa
commit (last but one) the "original branch" is redesign_interactions
* ccfd449 (HEAD -> develop) Require to return undef if no digits found
* 93dd5ff Merge pull request #4 from KES777/clean_api
|\
| * 39d82d1 Fix tc0118faests for debugging debugger internals
| * ed67179 Move &push_frame out of core
| * 2fd84b5 Do not lose info about call point
| * 3ab09a2 Improve debugger output: Show info about emitted events
| * a435005 Merge branch 'redesign_interactions' into clean_api
| |\
| | * a06cc29 Code comments
| | * d5d6266 Remove copy/paste code
| | * c0118fa Allow command to choose how continue interaction
| | * 19cb534 Emit &interact event
You should run:
git log c0118fa..HEAD --ancestry-path --merges
And scroll down to find last commit. Which is:
commit a435005445a6752dfe788b8d994e155b3cd9778f
Merge: 0953cac a06cc29
Author: Eugen Konkov
Date: Sat Oct 1 00:54:18 2016 +0300
Merge branch 'redesign_interactions' into clean_api
回答9:
This worked well enough for me to get the branch name from a detached head in a Jenkins workspace:
git show -s --pretty=%d