git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: Shawn Pearce <spearce@spearce.org>, Tommi Virtanen <tv@inoi.fi>
Cc: git@vger.kernel.org
Subject: Re: The git newbie experience
Date: Mon, 15 May 2006 01:39:08 -0700	[thread overview]
Message-ID: <7v1wuvvg0j.fsf@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: <20060515053133.GB28068@spearce.org> (Shawn Pearce's message of "Mon, 15 May 2006 01:31:33 -0400")

Shawn Pearce <spearce@spearce.org> writes:

>> I'd rather do that with a diff file that can be used to do a
>> 3-way (see how rebase does it with --full-index diff with am -3).
>> No point creating and forgetting to remove a throw away branch
>> and getting more complaints.
>
> How is a quick stash different from a topic branch?

The original version of my message in response to TV looked like
this.

 - Jack is a beginning user of git and does not (want to) understand
   the index (right now).

 - Jack works on branch X, say his HEAD points to X1. He has an edited,
   uncommitted files with the names A, B and C.

 - Jack wants to pull new changes made by others to his branch.
   But "git merge" invoked from "git pull" says he needs to stash
   away the local changes to do the merge.

 - Jack stashes away what he has been working on and cleans up
   his mess.

   git checkout -b stash ;# risks error when "stash" exists
   git commit -a -m 'Stashing WIP'
   git checkout master ;# assuming that was where he was

 - Jack then pulls.  There are merge conflicts in files D, E, ..., Z.

 - Jack resolves the merge conflicts and is ready to commit the resulting
   merge. Note files A, B and C do not have his unfinished work.

   There is no "if Jack does this or that" problem; he says "git
   commit -a" because that is the only "commit" command he knows
   about.

 - Jack then reapplies what he stashed away, and keeps working.

   git pull . --no-commit stash
   git branch -D stash

You have to teach the new user to (1) name something, only to
immediately discard it when he returns to what he was in the
middle of, (2) remember to clean up the temporary thing once he
is done lest he forgets to clean it up (and common names like
"stash", "tmp" will be reused by accident causing grief next
time he needs to do another stash), and (3) use of --no-commit
pull.

On the other hand, "git stash/unstash" workflow would be quite
simple:

	$ git stash >my.precious.state
        ... do whatever you want to deviate to
        $ git unstash <my.precious.state

Merge resolve might be needed while unstashing, but 
we are talking about pulling somebody else's work in "do
whatever" part, so that is something the user knows how to
perform anyway.

A quick and dirty stash implementation would go like this:

Stash is easy.

        #!/bin/sh
        # git stash
        git diff --binary HEAD
        git reset --hard

Unstash is a bit involved.

        #!/bin/sh
        # git unstash
        . git-sh-setup
        O_OBJECT=`cd "$GIT_OBJECT_DIRECTORY" && pwd`
        O_DIR=`cd "$GIT_DIR" && pwd`
        stash="$O_DIR/.stash$$"
        rm -fr "$stash.*"
        trap 'rm -rf $stash.*' 0
        cat >"$stash.patch"
        git-apply -z --index-info <"$stash.patch" >"$stash.list"
        GIT_INDEX_FILE="$stash.index"  \
        GIT_OBJECT_DIRECTORY="$O_OBJECT" \
        (
                mkdir -p "$stash.tmp" &&
                git-update-index -z --index-info <"$stash.list" &&
                git-write-tree >"$stash.base" &&
                cd "$stash.tmp" &&
                git-apply --binary --index <"$stash.patch" &&
                git-write-tree >"$stash.his"
        )
        his_tree=$(cat "$stash.his")
        orig_tree=$(cat "$stash.base")
        rm -fr "$stash.*"
        git-merge-resolve $orig_tree -- HEAD $his_tree

This is essentially the core of "am -3" logic; if you are going
to use this for real, you would probably want to see if the
patch applies cleanly before falling back on the three-way
merge, though.

  reply	other threads:[~2006-05-15  8:39 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-05-14 18:36 The git newbie experience Tommi Virtanen
2006-05-14 21:26 ` Junio C Hamano
2006-05-14 22:09 ` Junio C Hamano
2006-05-15  5:06   ` Tommi Virtanen
2006-05-15  5:18     ` Junio C Hamano
2006-05-15  5:31       ` Shawn Pearce
2006-05-15  8:39         ` Junio C Hamano [this message]
2006-05-15 16:46           ` Carl Baldwin
2006-05-15 20:47             ` Junio C Hamano
2006-05-15 20:42           ` Carl Worth
2006-05-15 21:10             ` Junio C Hamano
2006-05-15  5:27     ` Shawn Pearce

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=7v1wuvvg0j.fsf@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    --cc=spearce@spearce.org \
    --cc=tv@inoi.fi \
    /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).