2

Let's say I have a feature branch called feat which got merged into the master branch:

master feat
  |     .
 (1)    .
  |\    .
  | \   .
  |  \  .
  |   \ .
  |    \.  <-- create branch `feat` from `master`
  |     |
  |     |
  |    (2) <-- make a commit on `feat`
  |    /
  |   /
  |  /
  | /
  |/
 (3) <-- merge `feat` into `master`
  |

How can I tell from the merge commit (3) what the source branch for that commit was (feat)?

I found that you can get a list of branch names given a commit hash by running git branch --contains <commit>, but then I'm still left with the problem that I don't know the commit hash of the last commit of the source branch (2).

Edit:
No, Finding what branch a Git commit came from doesn't answer my question. Please read the last paragraph of this question.

Forivin
  • 14,780
  • 27
  • 106
  • 199
  • 3
    What if the branch `feat` was deleted in the meantime? In general this is not possible, a commit is not associated with any particular branch. – mkrieger1 Jan 27 '20 at 09:19
  • 1
    Finding parents of the merge commit would be trivial, but infering a branch name will be a speculative exercise. – Romain Valeri Jan 27 '20 at 09:19
  • 1
    You have the commit hash into the merge commit for example `Merge: a308437 ce271ef`, and the commit message contains the branch names. Hard to understand how you can have a merge commit without the information you need. – Ôrel Jan 27 '20 at 09:20
  • 1
    To get the *n*th parent of a commit, you can use the `^n` syntax, i.e. if `m` is the merge commit then `m^1` (or `m^`) would be (1) and `m^2` would be (2). – mkrieger1 Jan 27 '20 at 09:20
  • Does this answer your question? [Finding what branch a Git commit came from](https://stackoverflow.com/questions/2706797/finding-what-branch-a-git-commit-came-from) – mkrieger1 Jan 27 '20 at 09:23
  • @mkrieger1 No that does not answer my question. (Read the last paragraph of my question.) The `feat` branch will not have been deleted at the point where I try to find it. – Forivin Jan 27 '20 at 09:28
  • @Ôrel Well, I'm looking for a more bulletproof way of doing this that doesn't rely on the user giving out that information in the commit message. I've also been thinking about squash merging feature branches into the master and using commit messages like `feat: Add feature xxxxx` so the `master` commit history becomes easier to read. – Forivin Jan 27 '20 at 09:36
  • 4
    Why is the name of the original branch something you want to recover? What kind of problem are you trying to solve by obtaining that piece of information? – Lasse V. Karlsen Jan 27 '20 at 09:40
  • @LasseV.Karlsen I'm using GitLab CI to automatically run certain scripts whenever a commit is pushed. When a commit on a `feat/*` or `hotfix/*` branch is pushed, a build for that project is created. Now when such a branch is merged into the master, the script should either deploy the hotfix build or the feat build. The script doesn't know which one though and that's why I need to determine the source branch name. – Forivin Jan 27 '20 at 09:50
  • 2
    Existing CI build and deploy systems are sadly (and/or badly) flawed here. The only *really stable* name for a commit is its hash ID. A tag name is by-convention-stable. A branch name is in general completely useless, because the name may have been deleted since then—and worse, it might have been re-used for something else since then. Testing and deployment should be by hash ID, with perhaps some auxiliary database to make these more convenient for humans (i.e., the equivalent, or rough equivalent, of Git tags). – torek Jan 27 '20 at 09:54
  • @torek Well, in my case I know that the branch will still exist because I would only delete it after the CI script has finished doing its job. And I don't re-use branch names in general. I usually follow this convention `feat/-`. – Forivin Jan 27 '20 at 10:00

1 Answers1

0
git branch --contains HEAD^2 --merge |grep -v master

If HEAD is the (3) commit from your schema, HEAD^2 will be the (2) commit

git branch --contains HEAD^2 will show the branch with the commit use --merge to only show the ones merged into your branch, then use grep -v master to remove the master branch

With a commit id this will be

git branch --contains baa46815a954779c78b722ade9d01a9da5781a58^2 --merge |grep -v master
Ôrel
  • 7,044
  • 3
  • 27
  • 46