* who's on first? - following first parent and merge-management @ 2012-03-07 5:36 Neal Kreitzinger 2012-03-07 7:37 ` Junio C Hamano 0 siblings, 1 reply; 13+ messages in thread From: Neal Kreitzinger @ 2012-03-07 5:36 UTC (permalink / raw) To: git "first parent" and "follow first parent" are mentioned frequently in git documentation. This seems to imply that its pretty important. That would imply it should be intentional (planned). Who is "first parent"? Who is "first parent" _meant_ to be? What is "follow first parent" _meant_ to show? (I've been on the rebase track until now so I'm "new" to git-merge's.) Symptomatically, I think "first parent" is the branch you were on when you did the merge. That would mean the first parent can change depending on your merge-management practices. This affects the results that "follow first parent" produces. For example: $ git log --first-parent --oneline origin/master deadbee some commit x Scenario A: "First-Parent Flip-Flop" (some users are doing this) (1) I commit on local master. USER=foo $ git checkout master && hack && git commit -a -m "foo commit 1" $ git log --first-parent --oneline master foo1111 foo commit 1 deadbee some commit x (2) You push to canonical master. USER=bar $ git checkout master && hack && git commit -a -m "bar commit 1" $ git log --first-parent --oneline master bar1111 bar commit 1 deadbee some commit x $ git push origin HEAD && git fetch origin $ git log --first-parent --oneline origin/master bar1111 bar commit 1 deadbee some commit x (3) I merge canonical master w/my master and push. USER=foo $ git checkout master && git pull origin $ git log --first-parent --oneline master mrg1111 Merge branch 'master' of file:///root/BARE foo1111 foo commit 1 deadbee some commit x $ git push origin HEAD && git fetch origin $ git log --first-parent --oneline origin/master mrg1111 Merge branch 'master' of file:///root/BARE foo1111 foo commit 1 deadbee some commit x (4) You merge canonical master w/your master and push. USER=bar $ git checkout master && hack && git commit -a -m "bar commit 2" $ git log --first-parent --oneline master bar2222 bar commit 2 bar1111 bar commit 1 deadbee some commit x $ git pull origin $ git log --first-parent --oneline master mrg2222 Merge branch 'master' of file:///root/BARE bar2222 bar commit 2 bar1111 bar commit 1 deadbee some commit x $ git push origin HEAD && git fetch origin $ git log --first-parent --oneline origin/master mrg2222 Merge branch 'master' of file:///root/BARE bar2222 bar commit 2 bar1111 bar commit 1 deadbee some commit x This "flip-flop" practice does not seem right to me. Please comment. Scenario B: "First-Parent Consistency" (1) I commit on local master. USER=foo $ git checkout -b foo-topic master && hack && git commit -a -m "foo commit 1" $ git log --first-parent --oneline foo-topic foo1111 foo commit 1 deadbee some commit x (2) You push to canonical master. USER=bar $ git checkout -b bar-topic master && hack && git commit -a -m "bar commit 1" $ git log --first-parent --oneline bar-topic bar1111 bar commit 1 deadbee some commit x $ git checkout master && git merge bar-topic && git push origin HEAD && git fetch origin $ git log --first-parent --oneline origin/master bar1111 bar commit 1 deadbee some commit x (3) I merge --no-ff into master and push. USER=foo $ git checkout master && git pull --ff-only origin $ git log --first-parent --oneline master bar1111 bar commit 1 deadbee some commit x $ git-merge foo-topic $ git log --first-parent --oneline master mrg1111 Merge branch 'foo-topic' bar1111 bar commit 1 deadbee some commit x $ git push origin HEAD && git fetch origin $ git log --first-parent --oneline origin/master mrg1111 Merge branch 'foo-topic' bar1111 bar commit 1 deadbee some commit x (4) You merge --no-ff into master and push. USER=bar $ git checkout bar-topic && hack && git commit -a -m "bar commit 2" $ git log --first-parent --oneline bar-topic bar2222 bar commit 2 bar1111 bar commit 1 deadbee some commit x $ git checkout origin && git pull --ff-only origin $ git log --first-parent --oneline master mrg1111 Merge branch 'foo-topic' bar1111 bar commit 1 deadbee some commit x $ git merge bar-topic $ git log --first-parent --oneline master mrg2222 Merge branch 'bar-topic' mrg1111 Merge branch 'foo-topic' bar1111 bar commit 1 deadbee some commit x $ git push origin HEAD && git fetch origin $ git log --first-parent --oneline origin/master mrg2222 Merge branch 'bar-topic' mrg1111 Merge branch 'foo-topic' bar1111 bar commit 1 deadbee some commit x This "consistency" scenario seems better, but I'm not sure if its right. Git seems to "like it" in that the merge messages make more sense. Please comment. Please advise on "first parent" intent, best-practices, and pitfalls, or documentation that explains it. (I haven't found documentation that directly explains "first parent theory and practice". I've seen many references to "first parent" and its implied meaning that I'm supposed to "just know" or deduce). Thanks in advance for any pointers. v/r, neal ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-07 5:36 who's on first? - following first parent and merge-management Neal Kreitzinger @ 2012-03-07 7:37 ` Junio C Hamano 2012-03-08 6:13 ` Junio C Hamano 0 siblings, 1 reply; 13+ messages in thread From: Junio C Hamano @ 2012-03-07 7:37 UTC (permalink / raw) To: Neal Kreitzinger; +Cc: git Neal Kreitzinger <nkreitzinger@gmail.com> writes: > Please advise on "first parent" intent, best-practices, and pitfalls, > or documentation that explains it. (I haven't found documentation > that directly explains "first parent theory and practice". I've seen > many references to "first parent" and its implied meaning that I'm > supposed to "just know" or deduce). A short conclusion: if you take "first parentness" very seriously, neither of your two approaches are optimal, but that does not make you a bad person. It is just that "log --first-parent" is not the best way to get an overview of the history for your workflow. The mechanical definition of "first parent" is that: - A merge is a commit with more than one parent. - When you run "merge", you are on one commit, HEAD, taking changes made by "other branches" you are merging into "your history" (whose definition is "the commit-dag leading to your HEAD commit"), and record the resulting tree as a new commit. - This new commit records all its parents, one of them being your old "HEAD" and the rest being "other branches" you merged into "your history". They are recorded in that order in the resulting commit ("git cat-file commit HEAD" after a merge to see them). Hence, the first parent of a merge is the HEAD the committer was at when s/he ran "git merge". It's late so I won't go into the details of what the implications of this is in this message. Perhaps tomorrow when/if I have time. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-07 7:37 ` Junio C Hamano @ 2012-03-08 6:13 ` Junio C Hamano 2012-03-08 7:14 ` Jeff King 2012-03-08 7:49 ` Jonathan Nieder 0 siblings, 2 replies; 13+ messages in thread From: Junio C Hamano @ 2012-03-08 6:13 UTC (permalink / raw) To: Neal Kreitzinger; +Cc: git Junio C Hamano <gitster@pobox.com> writes: > The mechanical definition of "first parent" is that: > > - A merge is a commit with more than one parent. > > - When you run "merge", you are on one commit, HEAD, taking changes > made by "other branches" you are merging into "your history" > (whose definition is "the commit-dag leading to your HEAD > commit"), and record the resulting tree as a new commit. > > - This new commit records all its parents, one of them being your > old "HEAD" and the rest being "other branches" you merged into > "your history". They are recorded in that order in the resulting > commit ("git cat-file commit HEAD" after a merge to see them). > > Hence, the first parent of a merge is the HEAD the committer was at > when s/he ran "git merge". Given the above definition, the first thing to realize is that "the first parent" is primarily a local concept. If you are looking at one commit on a run of "a single strand of pearls", it only has one parent (i.e. its first parent), and it is the state the committer was on when he made the commit. If you are looking at a merge, its first parent is the commit the person who made that merge was on. Because of this local nature of first-parenthood, depending on the way how your project works, following the first parent chain all the way down to the root, i.e. "git log --first-parent", may or may not give an output that makes sense. "git show HEAD~250" has the same issue. An extreme example is where Git is used merely as a better CVS, where everybody works on his own "master", e.g. $ git clone $central mine && cd mine ... begin repeating from here ... $ git pull ;# this may get "already up-to-date" or create a merge $ work; work; work; git commit $ work; work; work; git commit $ git pull ;# this may create a merge or get "already up-to-date" ... optionally ... $ git push ... go back and repeat ... Imagine many people are doing the above simultaneously against the same shared central repository. Because everybody can create a "merge" when he is on his latest commit that may not even yet be ready for other's use, the first parent of a merge has no significance in the history of the overall project. The first parents of merges in such a project are "points at which random members of the project happened to be immediately before s/he pulled from the shared central repository". When you want a birds-eye view of changes between two versions of a project, "git log --first-parent v1.0..v2.0" gives no useful information in such a project. "git log --no-merges" or even "git shortlog" over the same range would generally work better. Insisting on "git pull --no-ff" in such a workflow makes things even worse for "first-parent summary". If everybody else were active while you were sleeping, and if you were up-to-date before going to bed, "git pull --no-ff" you do as the first thing in the morning from a habit will record a useless merge commit, and the _only_ two things such a commit records are (1) where the tip of the shared central repository was before you went to bed, and (2) where the tip of the shared central repository was when you came back to work. Neither is worth recording as part of the overall project history, obviously. There is the other end of extreme that first-parent summary works well. When there is a clear pecking order among project members, i.e. there is the central integrator "My history is the official one, yours are forks of it and I may merge them back to my history from time to time". Unless there is a fast-forward merge, in such a setting, "git log --first-parent" going all the way down to the root shows the way the history grew from the integrator's point of view, and use of "git pull --no-ff" by the integrator is one way to make sure that all merge commits yield this consistent view. He may have made individual commits (i.e. a single strand of pearls) on the mainline of the history, and they are shown as individual commits. He may have merged from a branch of his own or somebody else into the mainline of the history, and such a merge is shown as a single event that pulls all the commits from the side branch (and this is where "git merge --summary" becomes useful). It is no accident that we encourage users to focus the work made on a single branch (either his own or a remote) to a single topic---by doing so, it makes more sense to treat a merge of such a branch into the mainline as a single event that adds a feature (or fixes a bug, or whatever the topic of the branch wanted to achieve), relative to the state of the project immediately before the merge (i.e. "the first parent" of the merge). And "log --first-parent" is a way to summarize the history by culling the details of "side branches" and letting only the merge commits talk about what these side branches did to the history. It also is not an accident that "--first-parent" is a much later invention than "log" and "shortlog". Only after people got used to working with Git, they discovered the usefulness of the topic branch workflow, which is the key ingredient for any history that the first parenthood can giving a birds-eye view. Even if your project is using a central shared repository, you can take advantage of "first parent" summary by making sure you merge your work into the shared history, not the other way around like the workflow illustrated earlier in this message (or your "Flip-flop"). You would work like this: $ git clone $central mine && cd mine $ git checkout -b mywork ... begin repeating from here ... $ git checkout work ;# make sure you do not work on 'master' $ work; work; work; git commit $ work; work; work; git commit ... when you are done working on one logical topic ... $ git checkout master $ git pull --ff-only ;# the tip of shared history $ git merge mywork ;# note the first parent is the shared history $ test $ git push ... go back and repeat ... The resulting history may look like this: \ ---A---B---C---D---M \ / O---O---O---O mywork where A, B, C, D are the commits others made and published to the central shared repository (i.e. the shared project history). A is where the 'master' of the shared central repository was when you cloned and forked your "mywork" branch at. O are commits you made on your "side branch". By checking out your "master" and runnig "pull --ff-only", you would be checking out D to your working tree, and merging your work on the side branch to record M, which is what you publish and what becomes the tip of the shared history. By following the first parent chain starting at M, you can see that a single unit of your work (the goal you wanted to achieve on your "mywork" branch), which consists of 4 commits, was merged into the shared history at M, and before that, somebody else integrated his work at D, and so on. Note that the last push may race with other people and fail due to non fast-forward. In such a case, you have two possibilities. An easier way that violates the "first parent" principle for a short while is to do this: $ git pull ;# may conflict and need resolution $ test $ git push The resulting history may look like this: E---F \ / \ ---A---B---C---D---M---X \ / O---O---O---O mywork where E and F happened at the shared central repository while you were resolving merge M and testing the result. You pulled these changes and integrated into your history to create X, so the first parent of X becomes M and you would end up treating E and F as if they happened on a side branch, even though they are what people may consider the "mainline" of the the shared project history. If you are a purist, you could instead do this when "git push" is rejected in the original sequence: $ git reset --hard HEAD^ ;# cancel the merge of mywork $ git pull --ff-only ;# get the updated tip of shared history $ git merge mywork $ test $ git push which will result in a history like this: E---F---M' \ / / ---A---B---C---D---M / \ / / O---O---O---O--- mywork You abandon merge M ("reset --hard HEAD^" would take you back to D), update from the central repository again to be at F, and then merge your work (the same O--O--O--O) into it to create a new merge M', and make that the tip of the shared history by pushing it. Again, following the first parent chain starting from M', the history can be summarized as a series of merges of completed topics into the shared history. It is a judgement call if this is worth it (I personally do not think it is, but others may disagree). ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-08 6:13 ` Junio C Hamano @ 2012-03-08 7:14 ` Jeff King 2012-03-08 7:38 ` Junio C Hamano 2012-03-08 8:03 ` Johannes Sixt 2012-03-08 7:49 ` Jonathan Nieder 1 sibling, 2 replies; 13+ messages in thread From: Jeff King @ 2012-03-08 7:14 UTC (permalink / raw) To: Junio C Hamano; +Cc: Neal Kreitzinger, git On Wed, Mar 07, 2012 at 10:13:46PM -0800, Junio C Hamano wrote: > If you are a purist, you could instead do this when "git push" is > rejected in the original sequence: > > $ git reset --hard HEAD^ ;# cancel the merge of mywork > $ git pull --ff-only ;# get the updated tip of shared history > $ git merge mywork > $ test > $ git push This gave me an idea that I think is probably crazy, but that I hadn't seen mentioned before. What if the user could specify a partial ordering of refs, and we used that order when listing merge parents in the resulting commit. So for example, if you said that: refs/remotes/origin/master > refs/heads/master then doing: $ git checkout master $ git pull origin master would result in a "flipped" merge commit, with origin/master as the first parent, and master as the second. That makes the CVS-style central workflow (i.e. "oops, somebody else pushed, I'll just pull && push") follow the first-parent flow that people expect. You could extend it to topic branches, too ("refs/heads/master > refs/heads/jk/*"). Of course, depending on your workflow, you might _want_ to have them flipped. I.e., when it is not just laziness or lack of understanding, and you really are making a merge commit to say "topic XYZ depends on something that is now in master, so let's merge that in before continuing topic development". So I think the primary audience would be people doing clueless centralized-repo development. Of course you'd perhaps want to flip the merge message, too. And I do think people are overly-interested in --first-parent in the first place, so the effort of specifying the parent ordering like this is probably not worth it. I think when people ask about --first-parent, what they really want to say is "what happened on branch X, and what happened on this other branch". I wonder if we would do better to annotate the ref name of each side of the merge, and then people could follow a particular ref through history if they felt like it. That feels very un-git, as the DAG fundamentally does not care about the ref names. On the other hand, people do care, and we actually do have that information already in our stock merge commit messages What if we had something like "git log --follow-branch=master", and it was implemented something like: if commit has no parents add nothing to traversal else if commit has one parent consider parent for traversal (subject to usual UNINTERESTING, etc) else match commit message against /Merge branch '(.*)'( into (.*))?/ if $2 is empty, then set $2 to 'master' if $1 is 'master', add parent 2 to traversal if $2 is 'master', add parent 1 to traversal IOW, mine the commit messages to make a guess about the original state. I wonder how well it would work in practice. Git lets you do funny things like merge on a detached HEAD and assign the result to a ref. That may give you an odd merge message, but that's OK, because nothing is parsing it. But it would break a traversal like this. Like I said, I think these probably crazy ideas, but they were interesting enough to me to think through. Maybe they will inspire something not-crazy from somebody else. :) -Peff ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-08 7:14 ` Jeff King @ 2012-03-08 7:38 ` Junio C Hamano 2012-03-08 8:03 ` Johannes Sixt 1 sibling, 0 replies; 13+ messages in thread From: Junio C Hamano @ 2012-03-08 7:38 UTC (permalink / raw) To: Jeff King; +Cc: Neal Kreitzinger, git Jeff King <peff@peff.net> writes: > This gave me an idea that I think is probably crazy, but that I hadn't > seen mentioned before. > ... > You could extend it to topic branches, too ("refs/heads/master > > refs/heads/jk/*"). Of course, depending on your workflow, you might > _want_ to have them flipped. I.e., when it is not just laziness or lack > of understanding, and you really are making a merge commit to say "topic > XYZ depends on something that is now in master, so let's merge that in > before continuing topic development". It certainly is *fun* to think about, and in a way it is sort-of in line at least in spirit with the -m option to the "revert" command to give the user run-time control over the order of the parents when creating a new merge commit object. But I agree that people are overly and needlessly interested in first parenthood. > So I think the primary audience would be people doing clueless > centralized-repo development. Of course you'd perhaps want to flip the > merge message, too. And I do think people are overly-interested in > --first-parent in the first place, so the effort of specifying the > parent ordering like this is probably not worth it. As I already said in my first message in this thread, using shared central repository workflow does not make one a bad person, let alone clueless. It just means that the first parenthood is not a suitable tool for summarlizing their histories, and there are more suitable ones such as shortlog that would apply equally well to all workflows regardless of the parent order. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-08 7:14 ` Jeff King 2012-03-08 7:38 ` Junio C Hamano @ 2012-03-08 8:03 ` Johannes Sixt 2012-03-08 17:30 ` Junio C Hamano 1 sibling, 1 reply; 13+ messages in thread From: Johannes Sixt @ 2012-03-08 8:03 UTC (permalink / raw) To: Jeff King; +Cc: Junio C Hamano, Neal Kreitzinger, git Am 3/8/2012 8:14, schrieb Jeff King: > What if the user could specify a partial ordering of refs, and we used > that order when listing merge parents in the resulting commit. So for > example, if you said that: > > refs/remotes/origin/master > refs/heads/master > > then doing: > > $ git checkout master > $ git pull origin master > > would result in a "flipped" merge commit, with origin/master as the > first parent, and master as the second. I have wished for such a thing several times already. It happens when I have a topic with changes that trigger a complete rebuild of the project. When I merge it to master, I have to # on topic git checkout master #1 git merge topic #2 #1 triggers a rebuild, but I don't do a build. Then #2 again triggers a rebuild, but in reality the only changes since the last build are those from master since the topic forked (no, I can't use ccache). To avoid the situation, I jump through hoops by preparing an index and worktree with the merge result while I am on topic: # on topic git checkout --detach git merge master # triggers rebuild of only master's changes # merge result ready; carry it over to master and repeat the merge git reset --soft master git checkout master git merge topic # fails if content merge is necessary git checkout master -- file/needing/content/merge # (*) git merge topic # now succeeds This would not be necessary if the order of the merge parents could be specified, e.g.: # on topic git merge --into master (*) Jumping through these hoops make sense only if file/needing/content/merge is _not_ the one that triggers the complete rebuild. -- Hannes ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-08 8:03 ` Johannes Sixt @ 2012-03-08 17:30 ` Junio C Hamano 2012-03-09 12:05 ` Holger Hellmuth 0 siblings, 1 reply; 13+ messages in thread From: Junio C Hamano @ 2012-03-08 17:30 UTC (permalink / raw) To: Johannes Sixt; +Cc: Jeff King, Neal Kreitzinger, git Johannes Sixt <j.sixt@viscovery.net> writes: > I have wished for such a thing several times already. > > It happens when I have a topic with changes that trigger a complete > rebuild of the project. When I merge it to master, I have to > > # on topic > git checkout master #1 > git merge topic #2 > > #1 triggers a rebuild, but I don't do a build. Then #2 again triggers a > rebuild, but in reality the only changes since the last build are those > from master since the topic forked (no, I can't use ccache). > > To avoid the situation,... > This would not be necessary if the order of the merge parents could be > specified, e.g.: > > # on topic > git merge --into master I think the underlying mechanism needed to implement the above shares a lot with what Jeff called "crazy idea", but where you would want to be after such a merge may be different in these two cases. With the "crazy idea", you merge the other branch that happened to be the mainline into your work in reverse. You would explain such a merge as "I am merging early part of my topic that will eventually do X to mainline now, to make later conflict resolution easier, even though it is not yet complete" or something like that, and you will continue working on your topic starting from the resulting merge. The real project mainline will not be updated with this merge until the topic is complete (in other words, you do not push). I have a feeling that your "git merge-to master" may be different. You may explain the resulting commit as "This topic is complete for now and is ready for master", and the master gets updated with the result, but you may want to keep "topic" free of unrelated random other development that happened on "master" since they diverged. That way, "topic" can further be polished and you will leave the door open to merge it down to even older releases than "master". ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-08 17:30 ` Junio C Hamano @ 2012-03-09 12:05 ` Holger Hellmuth 2012-03-09 12:29 ` Johannes Sixt 0 siblings, 1 reply; 13+ messages in thread From: Holger Hellmuth @ 2012-03-09 12:05 UTC (permalink / raw) To: Junio C Hamano; +Cc: Johannes Sixt, Jeff King, Neal Kreitzinger, git On 08.03.2012 18:30, Junio C Hamano wrote: > Johannes Sixt<j.sixt@viscovery.net> writes: >> To avoid the situation,... >> This would not be necessary if the order of the merge parents could be >> specified, e.g.: >> >> # on topic >> git merge --into master > > I think the underlying mechanism needed to implement the above > shares a lot with what Jeff called "crazy idea", but where you would > want to be after such a merge may be different in these two cases. I don't think there is much question that you should still be in the same branch. Not because you necessarily want to be in that branch. But because it would be surprising if git-merge changed your branch sometimes and most times not. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-09 12:05 ` Holger Hellmuth @ 2012-03-09 12:29 ` Johannes Sixt 2012-03-09 13:25 ` Holger Hellmuth 0 siblings, 1 reply; 13+ messages in thread From: Johannes Sixt @ 2012-03-09 12:29 UTC (permalink / raw) To: Holger Hellmuth; +Cc: Junio C Hamano, Jeff King, Neal Kreitzinger, git Am 3/9/2012 13:05, schrieb Holger Hellmuth: > On 08.03.2012 18:30, Junio C Hamano wrote: >> Johannes Sixt<j.sixt@viscovery.net> writes: >>> To avoid the situation,... >>> This would not be necessary if the order of the merge parents could be >>> specified, e.g.: >>> >>> # on topic >>> git merge --into master >> >> I think the underlying mechanism needed to implement the above >> shares a lot with what Jeff called "crazy idea", but where you would >> want to be after such a merge may be different in these two cases. > > I don't think there is much question that you should still be in the same > branch. Not because you necessarily want to be in that branch. But because > it would be surprising if git-merge changed your branch sometimes and most > times not. I don't think that it is so clear-cut. And for this reason, I would even go as far as to suggest that you should end up with a detached HEAD. Before the merge we have this situation: --o--o--o--o <- master \ o--o--o--X <- topic The result of 'git merge --into master' must advance branch master by the merge commit (I think there is no doubt about this): --o--o--o--o---M <- master \ / o--o--o--X <- topic Also, the index and worktree must match M (no doubt, either, IMO). But what does HEAD refer to? I see three possibilities: 1. master; as you say, this may be surprising if we were on topic before the branch. 2. topic; but then the index would be dirty because it does not match X. 3. M, i.e. a detached HEAD; this is just a compromise and a fat warning at the end of the merge output would be necessary that instructs the user to checkout a suitable branch. Now that I have tossed around these ideas, there's another caveat: What if the merge fails due to a conflict? After the conflicts were resolved, 'git commit' is needed to complete the merge. But this would create the commit where HEAD points to. IOW, we have to chose option 1 so that the merge commit advances master. Would this be less surprising if the option were named --checkout-into? -- Hannes ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-09 12:29 ` Johannes Sixt @ 2012-03-09 13:25 ` Holger Hellmuth 2012-03-09 16:26 ` Junio C Hamano 0 siblings, 1 reply; 13+ messages in thread From: Holger Hellmuth @ 2012-03-09 13:25 UTC (permalink / raw) To: Johannes Sixt; +Cc: Junio C Hamano, Jeff King, Neal Kreitzinger, git On 09.03.2012 13:29, Johannes Sixt wrote: > Am 3/9/2012 13:05, schrieb Holger Hellmuth: >> On 08.03.2012 18:30, Junio C Hamano wrote: >>> Johannes Sixt<j.sixt@viscovery.net> writes: >>>> To avoid the situation,... >>>> This would not be necessary if the order of the merge parents could be >>>> specified, e.g.: >>>> >>>> # on topic >>>> git merge --into master >>> >>> I think the underlying mechanism needed to implement the above >>> shares a lot with what Jeff called "crazy idea", but where you would >>> want to be after such a merge may be different in these two cases. >> >> I don't think there is much question that you should still be in the same >> branch. Not because you necessarily want to be in that branch. But because >> it would be surprising if git-merge changed your branch sometimes and most >> times not. > > I don't think that it is so clear-cut. And for this reason, I would even > go as far as to suggest that you should end up with a detached HEAD. > > Before the merge we have this situation: > > --o--o--o--o<- master > \ > o--o--o--X<- topic > > The result of 'git merge --into master' must advance branch master by the > merge commit (I think there is no doubt about this): > > --o--o--o--o---M<- master > \ / > o--o--o--X<- topic > > Also, the index and worktree must match M (no doubt, either, IMO). But > what does HEAD refer to? I see three possibilities: I see we have different ideas. I envisioned --into to be the equivalent of git checkout master git merge topic git checkout topic and in that case index and worktree would be topic naturally. But your caveat below would be even more problematic in this case. > 1. master; as you say, this may be surprising if we were on topic before > the branch. > > 2. topic; but then the index would be dirty because it does not match X. > > 3. M, i.e. a detached HEAD; this is just a compromise and a fat warning at > the end of the merge output would be necessary that instructs the user to > checkout a suitable branch. > > Now that I have tossed around these ideas, there's another caveat: What if > the merge fails due to a conflict? After the conflicts were resolved, 'git > commit' is needed to complete the merge. But this would create the commit > where HEAD points to. IOW, we have to chose option 1 so that the merge > commit advances master. > > Would this be less surprising if the option were named --checkout-into? Don't think so. It would make it clear where you end up but it would muddle/hide the original purpose of the parameter. "git merge --into xxx" sounds like a real sentence (Larry Wall would approve ;-). Guess we would have to rely on the documentation to make it clear that a branch switch happens. And a message "Changing to branch xxx" on STDOUT wouldn't hurt either. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-09 13:25 ` Holger Hellmuth @ 2012-03-09 16:26 ` Junio C Hamano 0 siblings, 0 replies; 13+ messages in thread From: Junio C Hamano @ 2012-03-09 16:26 UTC (permalink / raw) To: Holger Hellmuth; +Cc: Johannes Sixt, Jeff King, Neal Kreitzinger, git Holger Hellmuth <hellmuth@ira.uka.de> writes: > On 09.03.2012 13:29, Johannes Sixt wrote: >> Am 3/9/2012 13:05, schrieb Holger Hellmuth: >>> On 08.03.2012 18:30, Junio C Hamano wrote: >>>> Johannes Sixt<j.sixt@viscovery.net> writes: >>>> ... >>>> I think the underlying mechanism needed to implement the above >>>> shares a lot with what Jeff called "crazy idea", but where you would >>>> want to be after such a merge may be different in these two cases. >>> >>> I don't think there is much question that you should still be in the same >>> branch. Not because you necessarily want to be in that branch. But because >>> it would be surprising if git-merge changed your branch sometimes and most >>> times not. >> >> I don't think that it is so clear-cut. >> ... > I see we have different ideas. I envisioned --into to be the equivalent of > git checkout master > git merge topic > git checkout topic > > and in that case index and worktree would be topic naturally. That is why I rewrote it to "git merge-to master" in my response, and said that there are two slightly different workflow ingredients that can be implemented with a similar mechanism. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-08 6:13 ` Junio C Hamano 2012-03-08 7:14 ` Jeff King @ 2012-03-08 7:49 ` Jonathan Nieder 2012-03-08 22:52 ` Junio C Hamano 1 sibling, 1 reply; 13+ messages in thread From: Jonathan Nieder @ 2012-03-08 7:49 UTC (permalink / raw) To: Junio C Hamano; +Cc: Neal Kreitzinger, git Hi all, Junio C Hamano wrote: > Given the above definition, the first thing to realize is that "the > first parent" is primarily a local concept. [... and much nice explanation ...] Would you mind including this explanation as a new file with some name like <Documentation/howto/using-first-parent.txt>? I think the quoted explanation is very clear and I have not come up with any obvious tweaks to make to it, which is why I am simply suggesting this instead of sending a patch that would repeat the same text. Strawman abstract: | From: Junio C Hamano <gitster@pobox.com> | Date: Wed, 07 Mar 2012 22:13:46 -0800 | Subject: who's on first? - following first parent and merge-management | Abstract: In this article, JC describes the "log --first-parent" and | "merge --no-ff" options and what kind of history makes them useful. Hm? Jonathan ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: who's on first? - following first parent and merge-management 2012-03-08 7:49 ` Jonathan Nieder @ 2012-03-08 22:52 ` Junio C Hamano 0 siblings, 0 replies; 13+ messages in thread From: Junio C Hamano @ 2012-03-08 22:52 UTC (permalink / raw) To: Jonathan Nieder; +Cc: Neal Kreitzinger, git Jonathan Nieder <jrnieder@gmail.com> writes: > Junio C Hamano wrote: > >> Given the above definition, the first thing to realize is that "the >> first parent" is primarily a local concept. > [... and much nice explanation ...] > > Would you mind including this explanation as a new file with some name > like <Documentation/howto/using-first-parent.txt>? I think the quoted > explanation is very clear and I have not come up with any obvious > tweaks to make to it, which is why I am simply suggesting this instead > of sending a patch that would repeat the same text. > > Strawman abstract: > > | From: Junio C Hamano <gitster@pobox.com> > | Date: Wed, 07 Mar 2012 22:13:46 -0800 > | Subject: who's on first? - following first parent and merge-management > | Abstract: In this article, JC describes the "log --first-parent" and > | "merge --no-ff" options and what kind of history makes them useful. Everything I write here is open source, so in that sense I wouldn't mind, but I have a suspicion that building on existing gitworkflows document might be more appropriate, as opposed to a self-contained standalone document that has to be read by readers in addition to the other existing documents. The current gitworkflows document is detailed in describing how the history is built, but is fairly lacking in description on how the resulting history can be studied. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2012-03-09 16:26 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-03-07 5:36 who's on first? - following first parent and merge-management Neal Kreitzinger 2012-03-07 7:37 ` Junio C Hamano 2012-03-08 6:13 ` Junio C Hamano 2012-03-08 7:14 ` Jeff King 2012-03-08 7:38 ` Junio C Hamano 2012-03-08 8:03 ` Johannes Sixt 2012-03-08 17:30 ` Junio C Hamano 2012-03-09 12:05 ` Holger Hellmuth 2012-03-09 12:29 ` Johannes Sixt 2012-03-09 13:25 ` Holger Hellmuth 2012-03-09 16:26 ` Junio C Hamano 2012-03-08 7:49 ` Jonathan Nieder 2012-03-08 22:52 ` Junio C Hamano
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).