git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: Steven Grimm <koreth@midwinter.com>
Cc: Jakub Narebski <jnareb@gmail.com>, git@vger.kernel.org
Subject: Re: GIT vs Other: Need argument
Date: Wed, 18 Apr 2007 23:02:00 -0700	[thread overview]
Message-ID: <7vejmg9a1z.fsf@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: <7vy7kpaz9s.fsf@assigned-by-dhcp.cox.net> (Junio C. Hamano's message of "Wed, 18 Apr 2007 19:11:59 -0700")

Junio C Hamano <junkio@cox.net> writes:

> Steven Grimm <koreth@midwinter.com> writes:
>
>> And in particular -- this being the original topic of the thread --
>> when an svn user sees me doing that, they do not immediately think of
>> the fact that merging between immutable revisions may have some
>> benefits. They see me typing four commands (commit, fetch, rebase,
>> reset) to do the same thing they can do in one command with svn, and
>> conclude that git is harder to use.
>
> No arguments there.  While I know I will never use such a
> workflow myself, I think it makes sense to _allow_ local
> changes to be merged to the new revision if the user chooses to
> use such a workflow.

Actually, there is one thing that makes this much easier to do
in SVN.  It is its centralized nature.

If you have this sequence:

	(1) update and sync with the repository
        (2) you work alone, without committing
        (3) while you do (2), other people make commits
        (4) you update from the repository

Because of its central nature, the commits made in (3) are
always proper descendant of the commit you are basing your work
on in (2).  So at point (4), the resolution you would need to
perform is this "merge".

          (2).............M?
         /               . 
	1-----3a-3b-3c-3d

    Notational convention: Solid lines and unparenthesized
    letters are actual commits and ancestry in these pictures.
    Letters in parentheses and dotted lines are locally modified
    states and derivations of these states from commits.

But because there is no "commit" that records the work you did
in (2) alone, you can afford to 3-way merge whatever conflict
you get at M and you do not even record M as a merge.  The
result simply becomes a proper descendant of 3, which is still
uncommitted local change.

                          (2')
                         .
	1-----3a-3b-3c-3d


The patch series I "vaguely recalled" in my previous message
handled this special case where the branch being merged
(i.e. 3d) was a fast-forward of the current commit (i.e. 1).

However, in git, you do not necessarily work that way.  As you
admitted, the ability to commit locally is what's different.


          2a---2b..(2c)...M?
         /               .
	1-----3a-3b-3c-3d

If (4) happened after you've accmulated local commits 2a, and
2b, and you have local changes (your state 2c is different from
your tip, 2b, but is uncommitted, and kept in the working tree
alone), you usually do not want to resolve the mess to make a
commit M, pretend M is a proper descendant of 3d, depending on
the final structure you are trying to achieve (the mess may come
from interactions between 3's and 2a or 2b, or interactions
between 3's and 2c).

There are three possible commit ancestry structures you would
want to eventually reach, and three distinct sets of steps to
reach those structures.

 1. Perfect what you were in the middle of, and then perform a
    merge.  IOW, you don't have to update from remote when you
    are not ready.

          2a---2b---2c----M
         /               / 
	1-----3a-3b-3c-3d

 2. Merge what has already been committed, excluding your
    unproven WIP that is in the working tree, and roll forward
    your local changes on top of it.

          2a---2b---------M..(2c')
         /               / 
	1-----3a-3b-3c-3d

 3. Always serialize by rebasing.  The structure you would want
    to end up with is like this:

                         2a'-2b'.(2c')
                        /
	1-----3a-3b-3c-3d

Among these three workflows, what is most natural in git is the
first one.  The tool natively supports it well.

For the second workflow, you would:

    2-a. first make a tentative commit 2c

	$ git commit

                 --2c
                /
          2a---2b
         /
	1-----3a-3b-3c-3d

    2-b. merge what was ready on your end and the other side:

	$ git checkout HEAD^ && git merge origin

                 --2c
                /
          2a---2b---------M
         /               / 
	1-----3a-3b-3c-3d

    2-c. roll forward the local change you have in 2c:

	$ git rebase --onto HEAD master
        $ git reset HEAD^

          2a---2b---------M...(2c')
         /               / 
	1-----3a-3b-3c-3d


This probably is the next best organization.  But you have to
realize that this requires you to resolve potential conflict
when creating M and then another conflict when rolling forward
your local changes.

    We probably could help automating this, but your "git pull"
    session transcript need to look like this:

	$ git pull origin
        First stashing away of your local changes...
	Resolving conflicts between 2b and 3d.
	Conflicted merge.  Please resolve and commit.
	$ edit ; test
        $ git commit ;# to record M
	Committed the merge result.
        You have stashed local changes further to roll forward.
        $ git unstash local-changes
        Resolving conflicts between M and 2c.
	Local changes conflicted during roll-forward.
        Leaving resulting mess in the working tree for you to sort out.
	$ 


To end up with the third graph, you would:

    3-a. first make a tentative commit 2c

	$ git commit

                 --2c
                /
          2a---2b
         /
	1-----3a-3b-3c-3d

    3-b. rebase

	$ git rebase origin

                          2a'--2b'--2c
                         /
	1-----3a-3b-3c-3d

    3-c. reset

	$ git reset HEAD^

                          2a'--2b'..(2c')
                         /
	1-----3a-3b-3c-3d


and I think that is what you have been doing.  Both the final
structure and the workflow are least "git-like" among these
three.

    If you want to automate this, you can use this four-liner
    shell script:

	#!/bin/sh
        git commit || exit
	git fetch origin || exit
        git rebase origin || exit
	git reset HEAD^

    Store this in $HOME/bin/git-sgpull, if you may, and you can
    even say "git sgpull" to invoke it.

    When 'rebase' does not get conflict, which is the bast case
    you are primarily complaining about, having to type three
    commands, this will run to the end with this single command
    and you will feel happier.

    When 'rebase' gets conflict, however, you would need to
    resolve and have it keep going, but that is something you
    cannot avoid.  You would need to remember that the final
    "reset HEAD^" needs to be issued from your shell, but that
    should be obvious.

  reply	other threads:[~2007-04-19  6:02 UTC|newest]

Thread overview: 120+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-17  9:02 GIT vs Other: Need argument Pietro Mascagni
2007-04-17  9:13 ` Matthieu Moy
2007-04-17 10:26   ` Andy Parkins
2007-04-17 14:32     ` Alex Riesen
2007-04-17 10:37   ` Martin Langhoff
2007-04-17 15:28   ` Linus Torvalds
2007-04-17 17:07     ` Matthieu Moy
2007-04-17 10:33 ` Martin Langhoff
2007-04-17 14:39   ` Alex Riesen
2007-04-25  8:58     ` Dana How
2007-04-25 10:35       ` Alex Riesen
2007-04-17 10:45 ` Tomash Brechko
2007-04-17 15:41   ` Guilhem Bonnefille
2007-04-17 17:18     ` Andy Parkins
2007-04-17 17:30       ` Shawn O. Pearce
2007-04-17 19:36         ` Marcin Kasperski
2007-04-18 10:05           ` Johannes Schindelin
2007-04-18 16:07             ` Linus Torvalds
2007-04-18 16:31               ` Nicolas Pitre
2007-04-18 16:49               ` Bill Lear
2007-04-18 17:43                 ` Matthieu Moy
2007-04-18 17:50                   ` Nicolas Pitre
2007-04-19 13:16                     ` Matthieu Moy
2007-04-19 18:44                       ` Petr Baudis
2007-04-20  9:04                         ` Matthieu Moy
2007-04-18 20:57                   ` Theodore Tso
2007-04-18 20:08               ` Guilhem Bonnefille
2007-04-18 20:19                 ` Linus Torvalds
2007-04-18 21:45                   ` Daniel Barkalow
2007-04-18 21:21                 ` Michael K. Edwards
2007-04-19  8:37                 ` Johannes Schindelin
2007-04-19 13:29                   ` Matthieu Moy
2007-04-19  9:24               ` Johannes Schindelin
2007-04-19 12:21                 ` Alex Riesen
2007-04-19 12:22                 ` Christian MICHON
2007-04-19 12:37                   ` Johannes Schindelin
2007-04-19 12:54                     ` Christian MICHON
2007-04-19 16:43                 ` Linus Torvalds
2007-04-19 17:49                   ` Marcin Kasperski
2007-04-19 20:57                     ` Linus Torvalds
2007-04-23 18:54                       ` Carl Worth
2007-04-23 19:52                         ` Josef Weidendorfer
2007-04-23 22:12                           ` Carl Worth
2007-04-23 22:23                         ` Junio C Hamano
2007-04-23 22:58                           ` Carl Worth
2007-04-23 23:24                             ` Linus Torvalds
2007-04-23 23:55                               ` Brian Gernhardt
2007-04-24  1:31                               ` Daniel Barkalow
2007-04-24  5:15                               ` Junio C Hamano
2007-04-24 14:23                                 ` J. Bruce Fields
2007-04-24 15:01                                   ` Linus Torvalds
2007-04-30  4:31                                     ` J. Bruce Fields
2007-04-25 13:12                                 ` Making git disappear when talking about my code (was: Re: GIT vs Other: Need argument) Carl Worth
2007-04-25 14:09                                   ` Carl Worth
2007-04-25 14:55                                     ` Linus Torvalds
2007-04-25 16:28                                       ` Carl Worth
2007-04-25 18:07                                         ` Nicolas Pitre
2007-04-25 19:03                                           ` Carl Worth
2007-04-25 19:17                                             ` Making git disappear when talking about my code Junio C Hamano
2007-04-25 19:22                                               ` Nicolas Pitre
2007-04-25 20:26                                               ` Carl Worth
2007-04-25 20:23                                             ` Making git disappear when talking about my code (was: Re: GIT vs Other: Need argument) Nicolas Pitre
2007-04-25 14:51                                   ` Linus Torvalds
2007-04-25 19:44                                   ` Daniel Barkalow
2007-04-25 19:56                                     ` Making git disappear when talking about my code Junio C Hamano
2007-04-25 20:29                                       ` Linus Torvalds
2007-04-25 20:32                                       ` Nicolas Pitre
2007-04-25 21:38                                       ` Daniel Barkalow
2007-04-25 20:29                                     ` Making git disappear when talking about my code (was: Re: GIT vs Other: Need argument) Carl Worth
2007-04-25 22:39                                       ` Daniel Barkalow
2007-04-25 20:31                                     ` Nicolas Pitre
2007-04-23 23:22                         ` GIT vs Other: Need argument Junio C Hamano
2007-04-19 20:49                   ` Johannes Schindelin
2007-04-20 15:54                   ` History cleanup/rewriting script for git Jan Harkes
2007-04-20 18:39                     ` Johannes Schindelin
2007-04-20 18:44                       ` Petr Baudis
2007-04-20 20:36                       ` Jan Harkes
2007-04-19 12:15               ` GIT vs Other: Need argument Marcin Kasperski
2007-04-19 12:33                 ` Johannes Schindelin
2007-04-19 12:42                   ` Marcin Kasperski
2007-04-19 13:36                     ` Johannes Schindelin
2007-04-19 14:27                     ` J. Bruce Fields
2007-04-19 12:45                   ` Theodore Tso
2007-04-19 12:46               ` [ANNOUNCE] Cogito is for sale Petr Baudis
2007-04-19 13:32                 ` Matthieu Moy
2007-04-19 20:23                 ` Junio C Hamano
2007-04-19 20:42                   ` Johannes Schindelin
     [not found]             ` <1176984208.30690.18.camel@cauchy.softax.local>
2007-04-19 12:28               ` GIT vs Other: Need argument Johannes Schindelin
2007-04-19 12:37                 ` Marcin Kasperski
2007-04-19 13:32                   ` Johannes Schindelin
     [not found]           ` <200704172239.20124.andyparkins@gmail.com>
2007-04-19 11:59             ` Marcin Kasperski
2007-04-19 12:48               ` Alex Riesen
2007-04-19 12:57               ` Andy Parkins
2007-04-20  6:22               ` Shawn O. Pearce
2007-04-20 13:03                 ` Eric Blake
2007-04-18 12:40       ` Guilhem Bonnefille
2007-04-18 13:26         ` Andy Parkins
2007-04-18 17:08           ` Steven Grimm
2007-04-19  0:33             ` Jakub Narebski
2007-04-19  1:24               ` Steven Grimm
2007-04-19  2:08                 ` Jakub Narebski
2007-04-19  8:48                   ` Johannes Schindelin
2007-04-19  8:57                     ` Julian Phillips
2007-04-19 19:03                     ` Steven Grimm
2007-04-19 21:00                       ` Johannes Schindelin
2007-04-19  2:11                 ` Junio C Hamano
2007-04-19  6:02                   ` Junio C Hamano [this message]
2007-04-19 18:18                     ` Steven Grimm
2007-04-19 23:30                       ` Junio C Hamano
2007-04-20  5:32                         ` Shawn O. Pearce
2007-04-20  9:04                         ` Jakub Narebski
2007-04-20 10:18                         ` Karl Hasselström
2007-04-20 10:39                           ` Junio C Hamano
2007-04-20 13:57                             ` Petr Baudis
2007-04-20  8:36                       ` Junio C Hamano
2007-04-20 16:42                         ` Steven Grimm
2007-04-18 20:54           ` Yann Dirson
2007-04-18  3:09     ` Sam Vilain
2007-04-18 20:49   ` Yann Dirson
2007-04-25  8:55   ` Dana How

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vejmg9a1z.fsf@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    --cc=jnareb@gmail.com \
    --cc=koreth@midwinter.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).