6

Yes this seems very similar to "Find the parent branch of a git branch" but I didn't find my answer there.

I think I want to know how to find my current branches parent, but I might be asking the wrong question. So I'll provide my scenario.

  1. Our organization has several long running release branches that do not get renamed (but eventually are deprecated after the release)

  2. Occasionally I create a feature branch from one of the release branches to work on a problem. It's a local feature branch.

  3. I get called away to work on some other item, some other release, etc.

  4. I come back to this feature and now I want to rebase it to the latest commit on which it was originally branched from. But enough time has passed that I cannot remember if this was branched from release x or release y

So how do I do this? In my mind, I thought I would just figure out what release branch I created my feature from, and then rebase to the last commit on that branch.

I know there are other organizational techniques that can be done to avoid this problem, such as always including the name of the base branch in my feature branch. But that ship has sailed.

Is there a git solution to the challenge I am having?

Community
  • 1
  • 1
John Rocha
  • 1,656
  • 3
  • 19
  • 30
  • Just to clarify, you are trying to step back along your feature branch until you find a commit that also belongs to a release branch? And you want to know the name of that release branch? – Mad Physicist Oct 26 '16 at 15:12
  • [This answer](http://stackoverflow.com/a/17843908/2988730) for the question you cited does exactly what you want. In fact, \@driodbot and \@gaal's comments below the question may provide a cleaner solution. – Mad Physicist Oct 26 '16 at 15:35
  • And yeah, the accepted answer for that one is definitely not optimal. – Mad Physicist Oct 26 '16 at 15:36

2 Answers2

6

This should do it for you:

git log --oneline \
  | cut -f 1 -d' ' \
  | (while read commit ; do
       other_branches="$(git branch --contains $commit | egrep -v '^\* ')"
       if [ -n "${other_branches}" ] ; then
         echo -e "${commit} is in:\n${other_branches}"
         break
       fi
     done)

This will go through this branch's commit log and for each commit, check which branches contain (are descendants of) that commit. As soon as it finds a commit that has a descendant that is not the current branch, it prints the commit hash, the other branches that contain that commit, and breaks out of the loop.

onlynone
  • 7,602
  • 3
  • 31
  • 50
  • This is a bit slow for large trees with lots of cross-merging because it will traverse large chunks of the tree repeatedly for each commit. (still +1 for sound concept) – Mad Physicist Oct 26 '16 at 19:34
  • @MadPhysicist We've got a huge git history with lots of merging (not sure about 'cross-merging`) and it was pretty fast for me. – onlynone Oct 26 '16 at 19:41
  • 2
    This is the only one that worked for me. Everything else threw this error: warning: ignoring release/2021.1; cannot handle more than 27 refs – justFatLard Jun 16 '21 at 00:37
  • @onlynone how to run this in windows 10? – Vivek Nuna Oct 02 '22 at 10:02
2

I think the answer can in fact be found in the question you cited, but not necessarily in the accepted answer.

  1. The first solution comes from this answer. A better answer than the one posted is found in the comments since the solutions in the comments use only standard unix commands:

    git show-branch | sed "s/].*//" | grep "\*" | \
        grep -v "$(git rev-parse --abbrev-ref HEAD)" | \
        head -n1 | sed "s/^.*\[//"
    

    This solution was developed by @droidbot an improved by @gaal.

  2. The second solution is in this answer by @ladiko, originally developed in @mark-reed's answer:

    git show-branch -a | awk -F'[]^~[]' '/^\*/ && !/'"$(git rev-parse --abbrev-ref HEAD)"'/ {print $2;exit}'
    

Both of these solutions will give you the name of the other branch containing the latest commit on your current branch that belongs to a branch other than your current one.

Community
  • 1
  • 1
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • I tried these and they aren't working. The first one gives no answer. Empty string for one of my branches. But I think the errors that result from the second one helped explain why. One of these branches was so old the base release branch has been deprecated. I'm checking other variations to see. – John Rocha Oct 26 '16 at 17:28
  • I am not sure what you mean by deprecated. – Mad Physicist Oct 26 '16 at 19:36
  • 4
    Tried both of these commands and I get several lines like: `warning: ignoring master; cannot handle more than 25 refs` – onlynone Oct 26 '16 at 19:41
  • and with the second I get `awk: cmd. line:1: /^\*/ && !/feature/my_branch/ {print $2;exit} awk: cmd. line:1: ^ syntax error ` – onlynone Oct 26 '16 at 19:44
  • @MadPhysicist, Sorry... deprecated == removed. It's a term used in SNMP and in many software houses for obsolete removed items. – John Rocha Oct 28 '16 at 19:40
  • @MadPhysicist I am also getting error warning: ignoring master; cannot handle more than 25 refs – Vivek Nuna Oct 02 '22 at 10:00