Get the name of the branch passed to git merge

I am writing hook-commit-msg (as pre-merge) and have to get the name of the merge source branch to go to the REST API. In other words, I need to get the branchname value fromgit merge <branchname>.

So far I've been trying to revisit MERGE_HEAD but it doesn't seem to be set yet when the trigger is fired. For now, I'm just using git revparse --abbrev-ref @ {- 1} to get the last branch I was on, but it doesn't necessarily always have to be the branch I want to merge.

The rule I'm trying to enforce is that users won't be able to merge their branch with master unless certain conditions are met. If there is a better hook to do this, then this will help too. Prepare-commit-msg is the only one that appears to have the commit type as an argument.

+3


source to share


1 answer


So far I've been trying to revisit MERGE_HEAD, but it doesn't seem to be installed yet when the hook is run.

It is right; but the problem is bigger. (And / or less, maybe! :-)) (Here I also remember Arkadiusz Drabczyk's comment : a git merge

that does not unify, i.e. one that fast-forwards-skips everything.)

First, think about what happens if the user does:

git merge a97131c

      

Which industry is this merger? Well, let's draw some graphs:

...--*--o--o--@   <-- blarg (HEAD), xtest
      \
       o--A--B   <-- br1
           \
            C   <-- br2, br3

      

HEAD

tells us what the current branch name is blarg

, so while the current commit is a commit @

(whose hash, perhaps 9fd178a

, for example), as soon as the merge commit is done, this is the name blarg

that will indicate a new merge commit.

Next, what's the commit a97131c

? It can be any of the commits A

, B

and C

. If it commits A

, it is not the end of the branch, so there is no suitable name to merge the branch. We just merge the commit A

so that the result is:

...--*--o--o--o   <-- xtest
      \        \
       o-----A--@   <-- blarg (HEAD)
             |\
             | B  <-- br1
              \
               C   <-- br2, br3

      

If a97131c

is a commit id B

we probably do git merge br1

, so the result would be:



...--*--o--o--o   <-- xtest
      \        \
       o        @  <-- blarg (HEAD)
        \      /
         A----B   <-- br1
          \
           C   <-- br2, br3

      

If a97131c

is a commit identifier C

, we are probably doing either git merge br2

or git merge br3

. (I'll leave drawing the resulting graph as an exercise, but note that, as before, the only name that moves is blarg

.)

Anyway, this is a long way of saying that even if you can get the name of a branch someone has checked out as an argument, and often, you can: it is allocated in .git/MERGE_MSG

- it doesn't matter. In Git, branch names are almost irrelevant. What is important is what happens.

So what can you do?

The rule I'm trying to enforce is that users won't be able to merge their branch with master unless certain conditions are met. If there is a better hook to do this, then this will help too. Prepare-commit-msg is the only one that appears to have the commit type as an argument.

It seems that the real goal is to disallow commits that result in any master

new commits or commits appearing on , unless those new commits satisfy some constraint. Of course, I don't know what your limits are, and I can only point out a few points:

  • git merge

    skips hooks pre-commit

    and commit-msg

    hooks in their entirety whenever the merge occurs automatically. Therefore, you will have to use the grappling hook prepare-commit-msg

    to catch this very early.

  • However, if a prepare-commit-msg

    hook goes out of non-zero during time git merge

    , the merge is still in progress. The next one git commit

    will merge. This operation launches hooks pre-commit

    and commit-msg

    (as opposed to a successful automatic merge). Again, even though commit is prevented by exiting a non-zero parameter, the merge is still in progress, ready to commit.

  • Users can always skip these hooks (or not install them). To actually provide something, you need to do it the moment the commit enters some repository that you manage. In many typical settings, this means in a centralized repository that individual developers work towards git push

    . You have to do this respecting the bindings pre-receive

    or update

    (and / or through Gitolite and its fancier systems).

All that has been said, it would still be nice to enforce some rules on a separate end of the developer so that they don't do a lot of work and think everything is fine and then go on to push and fail. The easiest way to deal with this is to write a shell that someone has to use: instead of running directly, git checkout master; git merge featureX

they start your shell, which does pre-checks, and then only makes calls git merge

if everything looks fine.

You can still do strict enforcement on a centralized server to prevent developers from circumventing these rules. But you give them a tool to help them, and you say, "If you want to avoid stumbling over the rules too late, use this tool."

+2


source







All Articles