1

I want to create an automatic staging branch creation process. When a user will push his changes to the git server, it should check the target branch - if the branch is a production branch it should instead push to a staging branch. (Later, a continuous integration process will start which will take care of pushing/merging the changes back into the production branch).

I have tried using git-hooks but I feel I am missing something. None of the git-hooks let me actually modify or manipulate the underlying git process and change the target branch, so I tried instead to use git-hooks to push to a production branch and then stop the rest of the process - but this causes the user to get a failure message and that is unwanted.

So I need a solution that will be:

  1. Seamless: Users won't know this is happening, as far as they know they are pushing their changes directly into their targeted branch and they get no error codes or confusing messages.
  2. Harmless: Not modify the targeted branch in any way.
  3. Magic: Silently create or update the staging branch associated with the target branch.
  4. Invisible: Should be server-side hook (such as update or pre-receive) so that users don't need to maintain their own hooks.

I previously asked this question, but it turned out to not be exactly what I wanted. So I created a new question with more clarification.

I am expecting answers to provide me with that "Aha!" realization of what I am missing. I have seen this process in action before and I know it's possible, I am just missing something. What I would really like to know is if its possible to modify the underlying git process with hooks, or to "hijack" the hooks return code so that it shows the user that everything went okay even though I stopped and change the process. Or perhaps another solution all together.

edit:

I myself am looking for a solution, and found something about Triangular Workflows which seems like it might be exactly what I want. But I can't figure out how to synchronize them automatically, it seems like every good solution requires some manual input somewhere along the line. Though I am certain that I have seen this setup working before and without the need to run any preparation scripts on the client side, and that the staging process was automagical.

Community
  • 1
  • 1
Inbar Rose
  • 41,843
  • 24
  • 85
  • 131

1 Answers1

0

You can't. As far as the receiving process on a server is concerned, you either accept a push, or reject it.

Furthermore, if you respond with "accept" to a push, the git repository of the user who is doing the push gets his remote-tracking branches updated with the assumption that the push completed. That is, if I am on host edithost and my origin is serverhost, and I run:

edithost$ git push origin branch

and it appears to succeed, my git will tell me that origin/branch now points to the same commit as my local branch.

(If I run git fetch origin my local git would, in this scenario, discover that, in fact, origin/branch is not updated. This is the same thing I will see if you really did completely accept the update, but then some admin quickly dived in and reset or force-pushed so that my commits got removed again. It's not harmful in a fundamental sense: as long as all users are expecting this behavior, they can accommodate it. But it's not seamless either: this is a seam.)

The only way to make all of this unsurprising is to have your users push to the integration branch, or to an intermediate server (or location within the server) where things that are named as if they were production branches, are actually integration branches. Of course this is not seamless either, but it's an unsurprising seam. :-) It's easy to arrange as well because git comes "out of the box" with the ability to do asymmetric fetch and push (see, e.g., remote.name.pushurl).

torek
  • 448,244
  • 59
  • 642
  • 775
  • Is there a way to setup this asymmetric method such that the users don't need to configure or change anything on their systems? (IE: server-side, or contained in the repo itself, and will propagate through clones, etc..) And can you perhaps link/expand some further information about it? (This is new to me and not sure where to look) – Inbar Rose Oct 29 '15 at 10:47
  • I don't think it can be done without having users do something to set up their configuration. But, you could have a script in the repository that people can run to do the setup, so as to hide the details. It could be as simple as a shell one liner, something like (totally untested and in need of obvious tweaking): `git config remote.origin.pushurl $(git config --get remote.origin.url | sed s/pullserver/pushserver/)`. Then setup is simply "clone this repository and then cd into it and run this script". – torek Oct 29 '15 at 20:20