How to get information where branch starts?

2019-02-05 08:56发布

问题:

As far as I know, commit object contains information only about parents, so if I have situation something like this:

 *  branch-1
 |
 o
 |
 o  master
 |
 o 

which is some kind of equivalent of

   *  branch-1
   |
   o
  /
 o  master
 |
 o 

but what if my master will go forward?

 o master
 |
 o *  branch-1
 | |
 o o
 |/
 o
 |
 o 

being on branch-1, git log --graph --decorate will show me only:

 *  branch-1
 |
 o
 |
 o
 |
 o 

if I know from which branch I was started, I can call git merge-base master branch-1, but what if I don't know from which branch I was started?


PS. I am still learning English, however sometimes I am making stupid mistakes. I am doing my best, writing questions and answers in English, however I would be very glad if you will edit my post in case of any mistakes. I promise, your effort will not be wasted.

回答1:

It's true that git doesn't permanently store this information, but you can likely find out anyway. Git has reflogs!

git reflog show <branch>

If the branch was created in the last 90 days (by default; use gc.reflogExpire to change this), the last line in that reflog will be the creation of the branch.

I'm assuming here that what you want to know is the commit a branch was created at, not which branch it forked from. That'd be a lot harder to find out - my best guess would be to, for each branch, take its position at the time your target branch was created and see if it includes the target branch's starting point.

The moral of the story here is that you should adopt a workflow in which you know which branch you forked your branch from. New features and bugfixes presumably will start at some stable point on your master branch, and subtopic branches can be named <topic>-<subtopic> as a reminder.

Edit:

Okay, so let's say you know a commit and a time (in this case, the commit and time a branch was created at). You're looking to find out what branch that commit was on at that point.

git for-each-ref --format='%(refname)' refs/heads/* | while read b; do
    if [ "$(git rev-parse $b@{$date_time})" = "$target_commit" ]; then
        echo "branch $b contained commit $target_commit at $date_time"
    fi
done

I think that should work as a bash script/one-liner. The idea: for every branch, take its position at the given date and time, and see whether it's the target commit. If you want to be even more flexible, you could test whether $(git merge-base $(git-rev-parse $b@{$date_time})) is the target commit; that is, whether the target commit was an ancestor of the given branch at that time.

And of course, in cases when your history is relatively clean, you can always use gitk --branches or git log --graph --branches [--oneline] to just see a nice picture.



回答2:

Git doesn't really have a concept of this, if you want to add this, you'd need to add a heuristic, because all git really cares about is attaching a label to a given commit in the tree.



回答3:

I guess you looking for

git log --graph --oneline --all

Check this thread out for a more detailed explaination. Stackoverflow answer