4

Just wondering what is the usual practice for merging back to the master, when the HEAD is likely to have been updated again since the last pull before the merge. To illustrate, in the following diagram, M is the intended merge point, but since master HEAD is updated to A1 by the time M is committed and ready to be pushed, M1 will become the new intended merge point, in other words a new merge has to be attempted.

master-----A----A1---...
            \     \
             M     M1
            /     /
local------B------

Note that I would prefer not to merge M and A1 because there might be A2, A3 down the line and if the problem recurs it just looks too messy to me with additional unintended merges. If the changes in local are sufficiently independent from those in master, sometimes I would just rebase on top of master which I find to be an easier solution. But at other times I am really hoping there is some way I can "re-use" the merging work I did for M, for M1.

prusswan
  • 6,853
  • 4
  • 40
  • 61
  • does everyone have push access to `master` or is it maintained by a single person who pulls from individual team members repositories? – Jacob Groundwater Nov 26 '11 at 09:34
  • everyone, the process is 'act on good sense, in general' – prusswan Nov 26 '11 at 09:36
  • If everyone were to push to their own repository and a single person owned `master` would that help? That person would essentially decide how to pull and in which order. I can explain in an answer if you like. – Jacob Groundwater Nov 26 '11 at 09:38
  • As in an arbitrator? Yes that is another way although I am looking for something that does not involve the consensus of other people. The downside is that that person will have to deal with all of the decision making, which is delegated to him. Nevertheless, if you post that as an answer I will upvote it. – prusswan Nov 26 '11 at 09:43
  • posted, i'd be happy to expand any parts that are unclear. – Jacob Groundwater Nov 26 '11 at 09:56

4 Answers4

2

Let's say each person on the team maintains their own repository. A single person on the team maintains what is collectively known as the main repository.

As team members work, they can pull from main but they do not push to main. During a pull, if there is a merge conflict that person will fix their own code.

Now the owner of main needs at the very least read access to each members repository. The owner of main then pulls from each repository in turn. If there are no merge conflicts, no problem. If there is a conflict then the owner of main aborts the commit, and let's the person who owns the code fix the conflict. Let's go over this part in detail

  1. main pulls from bob - ok; the merge is completed and published
  2. main pulls from tom - conflict; the merge is aborted
  3. the owner of main tells tom to pull the latest changes and fix the conflict
  4. tom can fix the conflict himself, then tell main to try again
  5. main pulls from tom - ok

This process is just repeated each day, or however often your integration cycle is.

While it definitely puts the burden onto a single person, that person does not have to fix any of the conflicts, it's a job that could be automated given the right motivation. This is how Linus does it for managing the kernel.

Jacob Groundwater
  • 6,581
  • 1
  • 28
  • 42
  • I realize in our current process, whoever that pushes a merge onto remote is implicitly obliged to fix any conflicts associated with that merge. Another issue is that a number of devs have freshly transitioned from svn and are actually advised to stick to `main` as they are not comfortable with the idea of operating with multiple remote branches. – prusswan Nov 26 '11 at 10:31
  • You should tell them is, by cloning a repo they're already using their own branch. It's definitely a different way of thinking, I had to get over my SVN brain. Now I much prefer the multiple remotes method. – Jacob Groundwater Nov 26 '11 at 10:36
  • A problem with main pulling from each repository is that they'll never be able to rebase their own work. Also, I don't understand how main is going to know when bob is ready with his changes (unless everyone is working in branches and only merging to their local main when they are ready for the main to get the changes - which seems like a "it works in my environment" situation), they may be mid-flight work, which you wouldn't want main picking up until they were complete. – Mark Fisher Nov 26 '11 at 11:35
  • The strategy used by github is a pull-request, where each person would sends exactly what commit they want pulled. You're right about rebase, however you _can_ technically rebase after a push, it just gets messy if another person has merged your work. Also you don't have to push until you want something merged. – Jacob Groundwater Nov 26 '11 at 11:53
1

It looks like a job for git rebase.

Workflow

You are working on a separate branch (let's call it local) and you do a few commits. When you are ready to push your changes, checkout the master branch and do a git pull. Checkout your local branch and do a git rebase master. This command will:

  1. put aside your changes/commits (on local) since master and local have diverged,
  2. do a fast forward merge with the master branch,
  3. recommit your original changes on the local branch. Keep in mind that the message, author and date of the commit remain the same, BUT the commit hash CHANGES. This happens because all the objects (commits, trees, blobs) are immutable and since the parent property of the commit changes, git will create another commit.

Implications of git rebase

Since the commit hash changes, you need to do the rebase only on LOCAL branches (ie. that are NOT pushed to remote).

Igor Popov
  • 9,795
  • 7
  • 55
  • 68
  • I actually do that a lot, but rebase is not suitable for all situations, sometimes I really want my commits for a feature branch to be indicated as such. – prusswan Nov 26 '11 at 09:13
1

We use a check-in token to co-ordinate this kind of issue. Whoever has it, is assured that no-one else is checking into master until it is released.

If you're co-located with the other devs checking into head, then use a physical token (an elephant/monkey/chicken - anything really, the cuter the better).

When we've had distributed development, we've used a wiki page with a table where the top is the person with the "token".

Mark Fisher
  • 9,838
  • 3
  • 32
  • 38
  • reasonable idea, but I think practically it is hard for me to convince the other devs to do it. Some of them really don't care about how many merges they take to push to the master – prusswan Nov 26 '11 at 09:15
  • then that's a process issue. it's something we've been doing for a long time, and is an essential part of ensuring that if you have the token, and get a green bar on your tests, there's nothing else going to affect your code, otherwise you're checking in against un-tested code if you don't retest after the merge. – Mark Fisher Nov 26 '11 at 09:21
  • I agree with you, but still looking for a way to simplify any merge work on my part. – prusswan Nov 26 '11 at 09:25
0

I finally figured out what I had in mind exactly, and the solution is simply to rebase the merge commit as described here: Rebasing a Git merge commit

Community
  • 1
  • 1
prusswan
  • 6,853
  • 4
  • 40
  • 61