Re: git pull opinion

Previous thread: Re: [PATCH 0/3] more terse push output by Junio C Hamano on Monday, November 5, 2007 - 2:14 pm. (1 message)

Next thread: Re: git pull opinion by Jakub Narebski on Monday, November 5, 2007 - 3:28 pm. (6 messages)
From: Aghiles
Date: Monday, November 5, 2007 - 2:52 pm

Hello,

I am not sure this is the best place to write about this. Anyway,
we just switched a couple of repositories to git (from svn) here
at work and one thing people find annoying is a pull into
a dirty directory. Before the "stash" feature it was even worse
but now we can type:

    git stash
    git pull
    git stash apply

But isn't that something we should be able to specify to the "pull"
command ? Additionally and if I am not mistakn, those commands will
create "dangling" commits and blobs. So one has to execute:

    git prune

Is there an "easier" way to pull into a dirty directory ? I am
asking this to make sure I understand the problem and not
because I find it annoying to type those 4 commands to perform
a pull (although some of my colleagues do find that annoying :).

For now, I am recommanding to my colleagues to commit very often
(even unfinished changes), pull, and then rebase the commits into
a more meaningful commit before pushing. Which seems to be a good
practice anyway,

Thank you for git,

- Aghiles.

ps; if someone is interested to hear what is the general opinion
on switching to git from svn in our company, I could elaborate.
-

From: Alex Riesen
Date: Monday, November 5, 2007 - 3:49 pm

Yes, please. And how did you manage to convince them to switch, if possible:
there are still some suckers here trying to do the same to their colleagues.

-

From: Miklos Vajna
Date: Monday, November 5, 2007 - 4:40 pm

who will run git stash clear? :)

- VMiklos
From: Aghiles
Date: Monday, November 5, 2007 - 9:16 pm

Yes you are right. By the way, in the context of merging into a
dirty tree, "git stash clear" seems to be a dangerous command:
there is a risk of loosing all your changes without a question
asked!

I know unix is a harsh world but ...

- Aghiles.
-

From: Benoit Sigoure
Date: Monday, November 5, 2007 - 10:29 pm

Be *very* careful, because it's worse than that.  If you run, say,  
`git stash clean', instead of `clear' (that's the sort of typo that  
quickly slips through), then it will stash all your changes in a new  
stash named "clean".  Once you realize you made a typo, you will most  
probably correct it and run `git stash clear' but...   Oops, you just  
wiped your changes that were in the "clean" stash.
That happened to me and other people I know, so now I'm utterly  
cautious when I start a command with "git stash".

As far as I remember, a patch was proposed to change this mis- 
behavior of "git stash" (one could argue that it's a PEBCAK issue,  
but I really think this command is *way* too dangerous) but I don't  
think it's been accepted at this time.

Cheers,

-- 
Benoit Sigoure aka Tsuna
EPITA Research and Development Laboratory


From: Ralf Wildenhues
Date: Tuesday, November 6, 2007 - 12:34 am

Hello,


I would love it if for once in the git world, there were a pair of
commands that would do the exact opposite of each other and where the
naive newbie (me) would immediately recognize that from their names:
  git stash push
  git stash pop

Both applied in this order should be a no-op on both the working tree,
the index, and also the stash.  There's room for extensions (pop
--keep-stash to not remove the stashed information), explicit naming of
stashes, doing multiple pops at once, and so on.  Please don't add more
of the git-push/git-pull, git-add/git-rm unsymmetrical interfaces.
Even if they're perfectly clear to git intimates, each one of them
takes precious extra time to learn due to this lack of symmetry.

Since I simply don't have the time resources to just implement that,
I'll thank you for your attention and go back to lurking mode now.

Thanks,
Ralf
-

From: Johannes Schindelin
Date: Tuesday, November 6, 2007 - 4:59 am

Hi,


You might as well be honest, and say that they are not time constraints, 
but lack of motivation. There is -- still! -- the patch "Teach "git 
reflog" a subcommand to delete single entries" in "pu" to delete 
single reflogs (and being in "pu" means it is only a fetch and a 
cherry-pick away).

Implementing that feature would be a piece of cake, but I will not do it, 
since _you_ want it, not _I_.  In spite of that, I implemented that reflog 
deleting, which was the hardest part of the exercise.

So, out, out with you, out of lurking mode!

Ciao,
Dscho

-

From: Ralf Wildenhues
Date: Tuesday, November 6, 2007 - 1:22 pm

No.  I will not do it, because the marginal cost of getting to
know not only git but also its source is too high for my precious
time ATM.  Maybe next year.

Will you do it for me if I buy you some beer?  If I promise to
(continue to) proofread git documentation for a couple of months?
If I do more audit of git's shell code, searching for nonportable
constructs?  Or if I promise to try to help you with any autotools

doesn't sound like it, but I would understand very well if it
needed that.

Please consider that division of work really can be advantageous
and that not all git users want to be or can be developers at all
times.

Cheers,
Ralf
-

From: Pierre Habouzit
Date: Tuesday, November 6, 2007 - 1:51 am

no it's a command issue. git stash <random non command name> should
_NOT_ be an alias to git stash save <random name>. Either the command
should be mandatory _or_ it should be a long option to avoid such kind
of conflicts.

  It's just a bad ui design.

--=20
=C2=B7O=C2=B7  Pierre Habouzit
=C2=B7=C2=B7O                                                madcoder@debia=
n.org
OOO                                                http://www.madism.org
From: Brian Downing
Date: Tuesday, November 6, 2007 - 5:26 pm

Complain to STDERR unless 'git stash save' is explicitly used.
This is in preparation for completely disabling the "default save"
behavior of the command in the future.

Signed-off-by: Brian Downing <bdowning@lavos.net>
---
 Documentation/git-stash.txt |    9 ++++-----
 git-stash.sh                |    8 +++++++-
 t/t3903-stash.sh            |   14 +++++++++++++-
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index c0147b9..61cf95d 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'git-stash' (list | show [<stash>] | apply [<stash>] | clear)
-'git-stash' [save] [message...]
+'git-stash' save [message...]
 
 DESCRIPTION
 -----------
@@ -39,8 +39,7 @@ OPTIONS
 save::
 
 	Save your local modifications to a new 'stash', and run `git-reset
-	--hard` to revert them.  This is the default action when no
-	subcommand is given.
+	--hard` to revert them.
 
 list::
 
@@ -119,7 +118,7 @@ perform a pull, and then unstash, like this:
 $ git pull
 ...
 file foobar not up to date, cannot merge.
-$ git stash
+$ git stash save
 $ git pull
 $ git stash apply
 ----------------------------------------------------------------
@@ -147,7 +146,7 @@ You can use `git-stash` to simplify the above, like this:
 +
 ----------------------------------------------------------------
 ... hack hack hack ...
-$ git stash
+$ git stash save
 $ edit emergency fix
 $ git commit -a -m "Fix in a hurry"
 $ git stash apply
diff --git a/git-stash.sh b/git-stash.sh
index f39bd55..a8b854a 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # Copyright (c) 2007, Nanako Shiraishi
 
-USAGE='[ | list | show | apply | clear]'
+USAGE='[save | list | show | apply | clear]'
 
 SUBDIRECTORY_OK=Yes
 . git-sh-setup
@@ -223,6 +223,12 @@ help | usage)
 	if test $# -gt 0 && test "$1" = save
 	then
 		shift
+	else
+		cat >&2 <<EOF
+'git ...
From: Brian Downing
Date: Tuesday, November 6, 2007 - 5:26 pm

Having 'git stash random stuff' actually stash changes is poor
user interface, due to the likelyhood of misspelling another legitimate
argument.  Require an explicit 'save' command instead.

Signed-off-by: Brian Downing <bdowning@lavos.net>
---
    This commit can be applied on top of the previous whenever it
    is decided "enough time" has passed for the hard behavior change
    of "git stash" to take place.

 git-stash.sh     |   16 +++++-----------
 t/t3903-stash.sh |    4 ++--
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index a8b854a..e900d40 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -219,17 +219,11 @@ create)
 help | usage)
 	usage
 	;;
-*)
-	if test $# -gt 0 && test "$1" = save
-	then
-		shift
-	else
-		cat >&2 <<EOF
-'git stash [message...]' is deprecated, please use
-'git stash save [message...]' instead.
-
-EOF
-	fi
+save)
+	shift
 	save_stash "$*" && git-reset --hard
 	;;
+*)
+	usage
+	;;
 esac
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index adfac4b..4896da0 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -73,13 +73,13 @@ test_expect_success 'unstashing in a subdirectory' '
 	git stash apply
 '
 
-test_expect_success 'stash with no args' '
+test_expect_failure 'stash with no args' '
 	echo 7 > file &&
 	test_tick &&
 	git stash
 '
 
-test_expect_success 'stash with bare message' '
+test_expect_failure 'stash with bare message' '
 	echo 8 > file &&
 	test_tick &&
 	git stash "a message"
-- 
1.5.3.5.1547.gf6d81-dirty
-

From: Johannes Sixt
Date: Wednesday, November 7, 2007 - 1:00 am

Can't we have these two?

	git-stash
	git-stash save [message...]

'git stash' without a message as an equivalent of 'git stash save' is still 
very handy.

-- Hannes

-

From: Wincent Colaiuta
Date: Wednesday, November 7, 2007 - 1:12 am

Agreed.

Wincent




-

From: Junio C Hamano
Date: Wednesday, November 7, 2007 - 1:02 am

Ok, but I would prefer to see this made into at least a
three-step process to ease the migration on users.  I do not
have any issue with a deprecation warning before the next big
release (1.5.4?).

The next step after this patch should not be the removal of
"defalut save".  Instead, introduce a boolean configuration,
stash.defaultsave, that defaults to false.  Without the
configuration, disable the "default save" (and do not even
mention the configuration variable, but do give the usage
message listing the commands).  But allow people to use the
"default save" behaviour with the configuration to help existing
users.  You can do this in the same release as above if you
want.

Then you would finally drop the "default save" in the next
big release after that "deprecation release".  But not before
that.

BTW, I've been quietly rewriting git-stash in C.  Be warned ;-)
-

From: Pierre Habouzit
Date: Wednesday, November 7, 2007 - 1:23 am

No arguments at all should not IMHO be deprecated, it's very useful,
and is not ambiguous. The issue with git stash <random> is that if you
thought you typed a command that doesn't in fact exists, you stash which
is not what you meant _at all_.

  When you type `git stash` you certainly want to stash, and it's what
it does.

Here is how it should work:

git-stash (list | show [<stash>] | apply [<stash>] | clear)
git-stash [save <message>]


--=20
=C2=B7O=C2=B7  Pierre Habouzit
=C2=B7=C2=B7O                                                madcoder@debia=
n.org
OOO                                                http://www.madism.org
From: Aghiles
Date: Tuesday, November 6, 2007 - 12:45 am

I think that people will use this a lot with the pull command and some
accidents will happen.  I am of the opinion that the semantics of this
command must be  changed.
Additionally, having "git stash [command]" and "git stash [argument]"
mixed together seems strange. One suggestion would be:

    git stash store/add/create [stash-name]
    git stash apply [stash-name]
    git stash clear <stash-name>  (accepts wildcards but no empty args)
    ...

- Aghiles.
-

From: Pascal Obry
Date: Tuesday, November 6, 2007 - 11:07 am

I'm using:

$ git config --global alias.update '!git stash && git pull && git stash
apply'

Then in a git repository just do:


Would be nice to hear about that indeed.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595

-

From: Uwe
Date: Wednesday, November 7, 2007 - 12:06 am

I wonder how this works, if the merge produces conflicts...

Best regards
Uwe

-- 
Uwe Kleine-König

http://www.google.com/search?q=1+year+in+days
-

From: Pascal Obry
Date: Wednesday, November 7, 2007 - 12:40 am

If you have conflicts it will not do the "git stash apply" as git pull
will return with an error. So you'll need to fix the conflicts and do
you the final git stash manually.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595

-

From: Junio C Hamano
Date: Monday, November 5, 2007 - 4:33 pm

You need to switch your mindset from centralized SVN workflow.

The beauty of distributedness is that it redefines the meaning
of "to commit".  In distributed systems, the act of committing
is purely checkpointing and it is not associated with publishing
the result to others as centralized systems force you to.

Stop thinking like "I need to integrate the changes from
upstream into my WIP to keep up to date."  You first finish what
you are currently doing, at least to the point that it is
stable, make a commit to mark that state, and then start
thinking about what other people did.  You may most likely do a
"git fetch" followed by "git rebase" to update your WIP on top
of the updated work by others.

Once you get used to that, you would not have "a dirty
directory" problem.
-

From: Bill Lear
Date: Monday, November 5, 2007 - 5:36 pm

I respectfully beg to differ.  I think it is entirely reasonable, and
not a sign of "centralized" mindset, to want to pull changes others
have made into your dirty repository with a single command.


Bill
-

From: Pierre Habouzit
Date: Monday, November 5, 2007 - 5:46 pm

I agree, I have such needs at work.  Here is how we (very informally)
work: people push things that they believe could help other (a new
helper function, a new module, a bug fix) in our master ASAP, but
develop big complex feature in their repository and merge into master
when it's ready.

  Very often we discuss some bugfix that is impeding people, or a
most-wanted-API. Someone does the work, commits, I often want to merge
master _directly_ into my current work-branch, because I want the
fix/new-API/... whatever.

  I don't believe it's because we have a centralized repository that I
have those needs, I would have the very same if I pulled changes
directly from my colleagues repository. The reason why I need it at work
is because there are some very vivid kind of changes, that only takes a
couple of diff lines, and that you _need_ for your work to be completed.
It's not really a matter of being fully up-to-date.

  Though to my delight, with the current tip-of-next git, I noticed that
many rebase and pull work in a dirty tree now :)

--=20
=C2=B7O=C2=B7  Pierre Habouzit
=C2=B7=C2=B7O                                                madcoder@debia=
n.org
OOO                                                http://www.madism.org
From: Alex Riesen
Date: Tuesday, November 6, 2007 - 12:38 am

How about merging just that "fix/new-API/... whatever" thing and not
the whole master, which should be a complete mess by now?

The way you explained it it looks like typical centralized workflow.
-

From: Pierre Habouzit
Date: Tuesday, November 6, 2007 - 1:31 am

No master only holds simple patches (few of them, typically half a

  Well I disagree, it's /part/ centralized. We have a two speed devel
method, one that works the old-centralized way for quick fixes, and a
more decentralized approach for big changes. It's a rather nice and
useful middle ground for a company where all programmers are within
earshot.

--=20
=C2=B7O=C2=B7  Pierre Habouzit
=C2=B7=C2=B7O                                                madcoder@debia=
n.org
OOO                                                http://www.madism.org
From: Aghiles
Date: Monday, November 5, 2007 - 11:30 pm

BitKeeper, for example, does a merge with a "dirty" directory.
I am not saying that git should behave the same way but I think
that this argument strengthens the point that it is not a
"centralized repository" mindset.

- Aghiles.
-

From: Alex Riesen
Date: Tuesday, November 6, 2007 - 12:40 am

Git does merge with dirty working directory. It just wont touch the
changed files and stop merging if the merge requires it.

-

From: Linus Torvalds
Date: Tuesday, November 6, 2007 - 9:36 am

Git does merge with a dirty directory too, but refuses to merge if it 
needs to *change* any individual dirty *files*.

And that actually comes from one of the great strengths of git: in git 
(unlike just about any other SCM out there) you can - and are indeed 
expected to - resolve merges sanely in the working tree using normal 
filesystem accesses (ie your basic normal editors and other tools).

That means that if there is a unresolved merge, you're actually expected 
to edit things in the same place where they are dirty. Which means that 
the merge logic doesn't want to mix up your dirty state and whatever 
merged state, because that is then not sanely resolvable.

Now, I do think that we could relax the rule so that "files that are 
modified must be clean in the working tree" could instead become "files 
that actually don't merge _trivially_ must be clean in the working tree". 
But basically, if it's not a trivial merge, then since it's done in the 
working tree, the working tree has to be clean (or the merge would 
overwrite it).

Doing a four-way merge is just going to confuse everybody.

So we *could* probably make unpack-trees.c: treeway_merge() allow this. 
It's not totally trivial, because it requires that the CE_UPDATE be 
replaced with something more ("CE_THREEWAY"): instead of just writing the 
new result, it should do another three-way merge.

So it's within the range of possible, but it's actually pretty subtle. The 
reason: we cannot (and *must*not*!) actually do the three-way merge early. 
We need to do the full tree merge in stage 1, and then only if all files 
are ok can we then check out the new tree. And we currently don't save the 
merge information at all.

So to do this, we'd need to:

 - remove the "verify_uptodate(old, o); invalidate_ce_path(old);" in 
   "merged_entry()", and actually *leave* the index with all three stages 
   intact, but set CE_UPDATE *and* return success.

 - make check_updates() do the three-way merge of "original ...
From: Aghiles
Date: Wednesday, November 7, 2007 - 2:25 pm

I really think this is a good idea. It seems to me that the first "bad"
surprise a svn/cvs/bk user will have is the result of a "git pull" command
on a dirty tree. With the proposed change, and if I understand correctly:
  - users that are used to commit often and fetch into clean trees
will never be bothered by this change.
  - users that are used to "update" often are expecting to resolve
conflicts in their working copy anyway.

In both cases git does not get in your way and everyone is happy.

- Aghiles
-

From: Johannes Schindelin
Date: Thursday, November 8, 2007 - 8:27 am

Hi,


But the latter ones will likely not understand why all of a sudden their 
working tree has to be clean sometimes (when there was no trivial 
merge possible).

Besides, I think it is not trivial to implement.

Not my itch,
Dscho

-

From: Linus Torvalds
Date: Friday, November 9, 2007 - 5:36 pm

Well, there will still be cases where people won't be happy.

That said, all fast-forward cases (which is, I guess, a fairly common way 
of operating for anybody who has ever just uses anoncvs to track others) 
would be handled by the "three-way-merge dirty data for trivial merges". 

So even if it would only handle that special case (and it handles a *lot* 
of other cases too!) it probably would be useful to some people.

That said, I still don't think I have the energy to actually try to do it. 
I do suspect it's not that hard, and I outlined where it would go, but 
it's really quite core and important code... IOW, this needs *lots* of 
deep thought and care.

			Linus
-

From: Andreas Ericsson
Date: Monday, November 5, 2007 - 5:54 pm

I find it much more convenient to just fetch them. I'd rather see
git-pull being given a --rebase option (which would ultimately mean
teaching git-merge about it) to rebase already committed changes on
top of the newly fetched tracking branch. It's being worked on, but
rather slowly.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231
-

From: Johannes Schindelin
Date: Monday, November 5, 2007 - 6:16 pm

Hi,


git-pull learning about --rebase does not mean teaching git-merge about 
it.  See my patch, which you (and others) failed to enthusiastically 
embrace, which is the sole reason it is stalled.

Ciao,
Dscho

-

From: Andreas Ericsson
Date: Tuesday, November 6, 2007 - 1:59 am

I must have missed it. Found the thread now though. Gonna try the patch in
production for a while and see how it pans out.

I'm curious about this hunk though. It seems unaffiliated with the --rebase
option as such, but was still in the patch. Would you care to clarify?

@@ -86,7 +95,6 @@ merge_head=$(sed -e '/	not-for-merge	/d' \
 
 case "$merge_head" in
 '')
-	curr_branch=$(git symbolic-ref -q HEAD)
 	case $? in
 	  0) ;;
 	  1) echo >&2 "You are not currently on a branch; you must explicitly"

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231
-

From: Johannes Schindelin
Date: Tuesday, November 6, 2007 - 5:05 am

Hi,


No, it is not unaffiliated.  If you go back to the patch, you will find 
that this line was not deleted, but moved to the start of git-rebase.sh.  
We need to know the branch name to get the config settings, and might just 
as well reuse the branch name for the merge_head case.

Hth,
Dscho

-

From: Andreas Ericsson
Date: Tuesday, November 6, 2007 - 5:08 am

Righto. I should learn to not write emails or read patches before 10am.
Thanks for clarifying.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231
-

From: Steven Grimm
Date: Monday, November 5, 2007 - 5:37 pm

I don't think wanting to pull in the middle of one's work has anything  
to do with centralized vs. decentralized, actually, though I do agree  
that it's a question of workflow.

For maybe 80% of my work, I do things "the git way" (lots of little  
local commits) and only sync up with other people when I've reached a  
good stopping point. Those are cases where I'm working in isolation on  
a new feature or a fix and will publish it as a whole unit when I'm  
done.

But the other 20% of the time, I'm working closely with another  
person. For example, I might be working with a front-end developer who  
is writing some nice snazzy JavaScript or Flash UI code to talk to my  
server-side code. And in that case, I really do want to be able to  
pull down his latest changes while I'm still in the middle of working  
on my own stuff, not least because it's only by testing with the real  
client -- where the button to invoke a particular piece of code on my  
side has just been added in the last 2 minutes -- that I can decide  
whether my work in progress is actually functional or not. (Unit tests  
only get you partway there.)

In other words, for traditional open-source-style distributed  
development where each repository is an isolated island that goes off  
and does its own thing, ignoring the outside world, the recommended  
git workflow is totally appropriate. It's also appropriate for a lot  
of in-house non-distributed development.

But for some classes of collaboration, where two or more people are  
essentially editing the same code base to work on the same feature and  
their changes are highly interdependent, that workflow is next to  
useless. There *is* no "I've gotten my code working and am ready to  
look at other people's changes now" stage until pretty late in the  
game. This kind of workflow happens a lot in commercial development in  
my experience.

Before git-stash, I did a lot of "commit; fetch; rebase; reset"  
sequences to support this kind of tight ...
From: Aghiles
Date: Monday, November 5, 2007 - 9:04 pm

This is very nice actually and we absolutely understand what a
commit means in the git world. Having the commit as a step
before publishing is very helpful (although some  concepts such

One particular situation in which this might not apply is when
two people work very closely on the same feature (as mentioned
by Steve Grimm in this thread) and one needs the changes
made by the other. This often happens when starting a new project,
as it is our case now :)

Thank you,

- Aghiles.
-

Previous thread: Re: [PATCH 0/3] more terse push output by Junio C Hamano on Monday, November 5, 2007 - 2:14 pm. (1 message)

Next thread: Re: git pull opinion by Jakub Narebski on Monday, November 5, 2007 - 3:28 pm. (6 messages)