git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Nanako Shiraishi <nanako3@bluebottle.com>
Cc: GIT <git@vger.kernel.org>
Subject: Re: [PATCH] Add git-save script
Date: Tue, 26 Jun 2007 18:05:42 -0700	[thread overview]
Message-ID: <7vsl8euryx.fsf@assigned-by-dhcp.pobox.com> (raw)
In-Reply-To: 7vmyyq2zrz.fsf@assigned-by-dhcp.pobox.com

Junio C Hamano <gitster@pobox.com> writes:

> Nanako Shiraishi <nanako3@bluebottle.com> writes:
> ...
>> +	save=$( (
>> +		i_tree=$(git-write-tree)
>> +
>> +		TMP=$GIT_DIR/.git-save-tmp
>> +		GIT_INDEX_FILE=$TMP
>> +		export GIT_INDEX_FILE
>> +
>> +		git-read-tree $i_tree
>> +		git-add -u
>> +		w_tree=$(git-write-tree)
>> +		rm $TMP
>> +		git-read-tree --prefix=base/ HEAD^{tree}
>> +		git-read-tree --prefix=indx/ $i_tree
>> +		git-read-tree --prefix=work/ $w_tree
>> +		git-write-tree
>> +		rm $TMP
>> +	) )
> ...
>  - Although you keep a separate tree for the index (before the
>    "git add -u" to grab the working tree changes) in the saved
>    data, it does not seem to be used.  It _might_ make sense to
>    replace "git add -u" with "git add ." so that work/ tree
>    contains even untracked (but not ignored) files, and on the
>    restore side unstage the paths that appear in work/ but not
>    in indx/.  I dunno.

I would like to take the last part of the sentence back.

I do not think "git add ." makes much sense.  The only case that
"add ." vs "add -u" may make a difference is the files that are
so new to your working tree that you haven't even added them to
the index.  But they would not be in your current HEAD, and they
would not have been added in the commit you are pulling, and if
that is not the case, git-merge would complain and bail out as
usual anyway.  I replied to your other message with something
about ".gitignore", but not everybody uses "ignore" mechanism
effectively, and "git add ." indeed would end up sucking all the
irrelevent cruft to w_tree for them, only to be extracted back
(because HEAD, i_tree and whichever commit you will later be
applying the stash to are not likely to have them).  Maybe we
could argue that those people with nonoptimal "ignore" list
deserve it, but I do not think it is worth the potential added
aggravation.

By the way, I initially liked the clever use of a single commit
that records the three trees in it, but now I am beginning to
really hate it.  I am suspecting that the primary reason you did
it that way was to reduce the number of commit objects used for
this purpose.  I personally do not think it is something we
would want to optimize for.

I think it would make much more sense to represent a stash like
this:

              .------o commit to represent index state
             /        \
     ---o---o----------o
            HEAD       commit to represent worktree state

That is, "index" and "worktree" state are represented as one
commit each, both are direct child of the HEAD, with an added
twist of the latter being also a child of the former.

This has an interesting side effect that I can do this:

	$ git show stash

to view what was in HEAD, index and working tree at the same
time (you can use "git stash show" to view the changes between
HEAD and worktree as before).

Being able to view this "evil merge" (this is a deliberately
evil merge, as you typically have huge differences between the
index and worktree when you need to stash) may not be that
interesting in the real life, but I think this is a good
demonstration of the reason why it is better to use more
straightforward ancestry structure to represent the stash.  By
not using a custom tree structure that is only understood by
"git stash", the user can use existing tools that operate on
normal ancestry chains.

>> ...
>> +	save_work
>> +	git reset --hard
>
> I am not absolutely sure if "git reset --hard" belongs here.
> You can certainly type one less command in your example sequence
> ("stash; pull; restore").  But I suspect there may be a case
> that would be more useful if "git save" did not do the reset
> itself.  I dunno....

I now think "git reset --hard" here is fine.

  parent reply	other threads:[~2007-06-27  1:05 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-23 13:02 [PATCH] Add git-save script Nanako Shiraishi
2007-06-23 15:05 ` Johannes Schindelin
2007-06-23 15:08   ` Bill Lear
2007-06-23 15:13     ` Johannes Schindelin
2007-06-25  6:32   ` しらいしななこ
2007-06-25  7:52     ` Junio C Hamano
     [not found]   ` <200706250632.l5P6Wu6B028140@mi0.bluebottle.com>
2007-06-25  7:45     ` Johannes Schindelin
2007-06-23 20:15 ` Junio C Hamano
2007-06-24 10:43   ` Nanako Shiraishi
2007-06-24 19:45     ` Junio C Hamano
2007-06-27  1:05   ` Junio C Hamano [this message]
2007-06-27  9:38     ` しらいしななこ

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

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

  git send-email \
    --in-reply-to=7vsl8euryx.fsf@assigned-by-dhcp.pobox.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=nanako3@bluebottle.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.
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).