* Re: why is git destructive by default? (i suggest it not be!)
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5V7wbFEDjCX7V>
@ 2008-06-24 1:47 ` David Jeske
2008-06-24 1:47 ` David Jeske
1 sibling, 0 replies; 113+ messages in thread
From: David Jeske @ 2008-06-24 1:47 UTC (permalink / raw)
To: git
As a new user, I'm finding git difficult to trust, because there are operations
which are destructive by default and capable of inadvertently throwing hours or
days of work into the bit bucket.
More problematic, those commands have no discernible pattern that shows their
danger, and they need to be used to do typical everyday things. I'm starting to
feel like I need to use another source control system on top of the git
repository in case I make a mistake. My philosophy is simple, I never never
never want to throw away changes, you shouldn't either. Disks are cheaper than
programmer hours. I can understand wanting to keep things tidy, so I can
understand ways to correct the 'easily visible changes', and also avoid pushing
them to other trees, but I don't understand why git needs to delete things.
For example, the following commands seem capable of totally destroying hours or
days of work. Some of them need to be used regularly to do everyday things, and
there is no pattern among them spelling out danger.
git reset --hard : if another branch name hasn't been created
git rebase
git branch -D <branch> : if branch hasn't been merged
git branch -f <new> : if new exists and hasn't been merged
git branch -m <old> <new> : if new exists and hasn't been merged
I've heard from a couple users that the solution to these problems is to "go
dig what you need out of the log, it's still in there". However, it's only in
there until the log is garbage collected. This either means they are
destructive operations, or we expect "running without ever collecting the log"
to be a valid mode of operation... which I doubt is the case.
Question: How about assuring ALL operations can be done non-destructivly by
default? Then make destructive things require an explicit action that follows a
common pattern.
Suggestion Illustration
-----------------------
Below is one illustration of how these commands could be changed to be entirely
non-destructive, while retaining the current functionality. It also allows you
to destroy stuff if you have lawyers breathing down your neck, or really really
can't afford the hard drive space for a couple lines of text (though I'll
personally make a donation to anyone in this state!) :)
1) Require the "--destroy" flag for ANY git operation which is capable of
destroying data such that it is unrecoverable. A narrow view of this is to only
consider checked-in repository data, and not metadata, such as the location of
a branchname. However, the broad view would be to include all/most metadata.
2) Make a pattern for branch names which are kept in the local tree, not
included in push/pull, not modifiable without first renaming, and not shown by
default when viewing all branch history. For example, "local-<date>-*"
3) make 'git reset --hard <commit>' safe
Automatically commit working set and make a branch name (if necessary) to avoid
changes being thrown away. The branch name could be of the form
"local-<date>-reset-<user>-<date>". If the user really wants to destroy it,
they could use the dangerous version "git reset --hard --destroy", or they
could just "git branch -d --destroy <branchname>" afterwords. Most users would
do neither.
4) make 'git rebase' safe
'rebase' would make a branch name before performing its operation, assuring it
was easy to get back to the previous state. Currently, "git rebase" turns this:
A---B---C topic
/
D---E---F---G master
Into this:
A'--B'--C' topic
/
D---E---F---G master
.. and in turn destroys the original changes. It would instead create this:
A--B--C (x) A'--B'--C' (y)
/ /
D---E------F-------G master
(x) - local-<date>-rebase-topic-<commit for G>
(y) - topic
5) make 'git branch' follow rule 1 above (safe without --destroy)
Using any of the following commands without --destroy would cause them to
create a branch "local-<date>-rename-<old branch name>", to prevet the
destruction of the old branch location:
git branch -d <branchname>
git branch -M <old> <new>
git branch -f <branchname>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: why is git destructive by default? (i suggest it not be!)
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5V7wbFEDjCX7V>
2008-06-24 1:47 ` why is git destructive by default? (i suggest it not be!) David Jeske
@ 2008-06-24 1:47 ` David Jeske
2008-06-24 17:11 ` Boaz Harrosh
1 sibling, 1 reply; 113+ messages in thread
From: David Jeske @ 2008-06-24 1:47 UTC (permalink / raw)
To: git
As a new user, I'm finding git difficult to trust, because there are operations
which are destructive by default and capable of inadvertently throwing hours or
days of work into the bit bucket.
More problematic, those commands have no discernible pattern that shows their
danger, and they need to be used to do typical everyday things. I'm starting to
feel like I need to use another source control system on top of the git
repository in case I make a mistake. My philosophy is simple, I never never
never want to throw away changes, you shouldn't either. Disks are cheaper than
programmer hours. I can understand wanting to keep things tidy, so I can
understand ways to correct the 'easily visible changes', and also avoid pushing
them to other trees, but I don't understand why git needs to delete things.
For example, the following commands seem capable of totally destroying hours or
days of work. Some of them need to be used regularly to do everyday things, and
there is no pattern among them spelling out danger.
git reset --hard : if another branch name hasn't been created
git rebase
git branch -D <branch> : if branch hasn't been merged
git branch -f <new> : if new exists and hasn't been merged
git branch -m <old> <new> : if new exists and hasn't been merged
I've heard from a couple users that the solution to these problems is to "go
dig what you need out of the log, it's still in there". However, it's only in
there until the log is garbage collected. This either means they are
destructive operations, or we expect "running without ever collecting the log"
to be a valid mode of operation... which I doubt is the case.
Question: How about assuring ALL operations can be done non-destructivly by
default? Then make destructive things require an explicit action that follows a
common pattern.
Suggestion Illustration
-----------------------
Below is one illustration of how these commands could be changed to be entirely
non-destructive, while retaining the current functionality. It also allows you
to destroy stuff if you have lawyers breathing down your neck, or really really
can't afford the hard drive space for a couple lines of text (though I'll
personally make a donation to anyone in this state!) :)
1) Require the "--destroy" flag for ANY git operation which is capable of
destroying data such that it is unrecoverable. A narrow view of this is to only
consider checked-in repository data, and not metadata, such as the location of
a branchname. However, the broad view would be to include all/most metadata.
2) Make a pattern for branch names which are kept in the local tree, not
included in push/pull, not modifiable without first renaming, and not shown by
default when viewing all branch history. For example, "local-<date>-*"
3) make 'git reset --hard <commit>' safe
Automatically commit working set and make a branch name (if necessary) to avoid
changes being thrown away. The branch name could be of the form
"local-<date>-reset-<user>-<date>". If the user really wants to destroy it,
they could use the dangerous version "git reset --hard --destroy", or they
could just "git branch -d --destroy <branchname>" afterwords. Most users would
do neither.
4) make 'git rebase' safe
'rebase' would make a branch name before performing its operation, assuring it
was easy to get back to the previous state. Currently, "git rebase" turns this:
A---B---C topic
/
D---E---F---G master
Into this:
A'--B'--C' topic
/
D---E---F---G master
.. and in turn destroys the original changes. It would instead create this:
A--B--C (x) A'--B'--C' (y)
/ /
D---E------F-------G master
(x) - local-<date>-rebase-topic-<commit for G>
(y) - topic
5) make 'git branch' follow rule 1 above (safe without --destroy)
Using any of the following commands without --destroy would cause them to
create a branch "local-<date>-rename-<old branch name>", to prevet the
destruction of the old branch location:
git branch -d <branchname>
git branch -M <old> <new>
git branch -f <branchname>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 1:47 ` David Jeske
@ 2008-06-24 17:11 ` Boaz Harrosh
2008-06-24 17:19 ` Boaz Harrosh
2008-06-24 18:18 ` Brandon Casey
0 siblings, 2 replies; 113+ messages in thread
From: Boaz Harrosh @ 2008-06-24 17:11 UTC (permalink / raw)
To: David Jeske; +Cc: git
David Jeske wrote:
> As a new user, I'm finding git difficult to trust, because there are operations
> which are destructive by default and capable of inadvertently throwing hours or
> days of work into the bit bucket.
>
> More problematic, those commands have no discernible pattern that shows their
> danger, and they need to be used to do typical everyday things. I'm starting to
> feel like I need to use another source control system on top of the git
> repository in case I make a mistake. My philosophy is simple, I never never
> never want to throw away changes, you shouldn't either. Disks are cheaper than
> programmer hours. I can understand wanting to keep things tidy, so I can
> understand ways to correct the 'easily visible changes', and also avoid pushing
> them to other trees, but I don't understand why git needs to delete things.
>
> For example, the following commands seem capable of totally destroying hours or
> days of work. Some of them need to be used regularly to do everyday things, and
> there is no pattern among them spelling out danger.
>
> git reset --hard : if another branch name hasn't been created
git reset --hard is special see below
> git rebase
> git branch -D <branch> : if branch hasn't been merged
> git branch -f <new> : if new exists and hasn't been merged
> git branch -m <old> <new> : if new exists and hasn't been merged
>
The rest of the commands are recoverable from the log as people said
but "git reset --hard" is not and should be *fixed*!
I use git reset --hard in to separate and distinct functions.
One - to move current branch head around from place to place.
Two - Throw away work I've edited
It has happened to me more then once that I wanted the first
and also got the second as an un-warned bonus, to the dismay
of my bosses. (What do I care if I need to write all this code
again)
I would like git-reset --hard to refuse if a git-diff HEAD
(both staged and unstaged) is not empty. with a -f / -n logic
like git-clean. (like git-clean none default config file override)
Now I know that the first usage above could be done with
git-branch -f that_branch the_other_branch. But that can
not be preformed on the current branch and local changes
are not lost.
Lots of other potentially destructive git-commands check for local
changes and refuse to operate. To remedy them git-reset --hard
is recommended. I would prefer if there was a git-reset --clean -f/-n
for the first case and git reset --hard only for the second usage
case.
My $0.017
Boaz
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 17:11 ` Boaz Harrosh
@ 2008-06-24 17:19 ` Boaz Harrosh
2008-06-24 19:08 ` Jakub Narebski
2008-06-24 18:18 ` Brandon Casey
1 sibling, 1 reply; 113+ messages in thread
From: Boaz Harrosh @ 2008-06-24 17:19 UTC (permalink / raw)
To: David Jeske; +Cc: git
Boaz Harrosh wrote:
> David Jeske wrote:
>> As a new user, I'm finding git difficult to trust, because there are operations
>> which are destructive by default and capable of inadvertently throwing hours or
>> days of work into the bit bucket.
>>
>> More problematic, those commands have no discernible pattern that shows their
>> danger, and they need to be used to do typical everyday things. I'm starting to
>> feel like I need to use another source control system on top of the git
>> repository in case I make a mistake. My philosophy is simple, I never never
>> never want to throw away changes, you shouldn't either. Disks are cheaper than
>> programmer hours. I can understand wanting to keep things tidy, so I can
>> understand ways to correct the 'easily visible changes', and also avoid pushing
>> them to other trees, but I don't understand why git needs to delete things.
>>
>> For example, the following commands seem capable of totally destroying hours or
>> days of work. Some of them need to be used regularly to do everyday things, and
>> there is no pattern among them spelling out danger.
>>
>> git reset --hard : if another branch name hasn't been created
>
> git reset --hard is special see below
>
>> git rebase
>> git branch -D <branch> : if branch hasn't been merged
>> git branch -f <new> : if new exists and hasn't been merged
>> git branch -m <old> <new> : if new exists and hasn't been merged
>>
> The rest of the commands are recoverable from the log as people said
> but "git reset --hard" is not and should be *fixed*!
>
> I use git reset --hard in to separate and distinct functions.
> One - to move current branch head around from place to place.
> Two - Throw away work I've edited
>
> It has happened to me more then once that I wanted the first
> and also got the second as an un-warned bonus, to the dismay
> of my bosses. (What do I care if I need to write all this code
> again)
>
> I would like git-reset --hard to refuse if a git-diff HEAD
> (both staged and unstaged) is not empty. with a -f / -n logic
> like git-clean. (like git-clean none default config file override)
>
> Now I know that the first usage above could be done with
> git-branch -f that_branch the_other_branch. But that can
> not be preformed on the current branch and local changes
> are not lost.
>
> Lots of other potentially destructive git-commands check for local
> changes and refuse to operate. To remedy them git-reset --hard
> is recommended. I would prefer if there was a git-reset --clean -f/-n
> for the first case and git reset --hard only for the second usage
> case.
Sorry
git-reset --clean -f/-n for removing local changes
git reset --hard for moving HEAD on a clean tree only
>
> My $0.017
> Boaz
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 17:19 ` Boaz Harrosh
@ 2008-06-24 19:08 ` Jakub Narebski
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5zrLdFEDjCV3U>
2008-06-25 8:57 ` Boaz Harrosh
0 siblings, 2 replies; 113+ messages in thread
From: Jakub Narebski @ 2008-06-24 19:08 UTC (permalink / raw)
To: Boaz Harrosh; +Cc: David Jeske, git
Boaz Harrosh <bharrosh@panasas.com> writes:
> Sorry
> git-reset --clean -f/-n for removing local changes
> git reset --hard for moving HEAD on a clean tree only
Wouldn't "git reset <commit-ish>" be enough then? It modifies where
current branch points to (as opposed to git-checkout modifying what is
the current branch), and it modifies index. What it doesn't modify is
working directory, but it is clean already.
So the solution is: don't use `--hard'.
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply [flat|nested] 113+ messages in thread[parent not found: <willow-jeske-01l5PFjPFEDjCfzf-01l5zrLdFEDjCV3U>]
* Re: why is git destructive by default? (i suggest it not be!)
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5zrLdFEDjCV3U>
@ 2008-06-24 20:04 ` David Jeske
2008-06-24 21:42 ` Brandon Casey
2008-06-24 22:21 ` Steven Walter
2008-06-24 20:04 ` why is git destructive by default? (i suggest it not be!) David Jeske
1 sibling, 2 replies; 113+ messages in thread
From: David Jeske @ 2008-06-24 20:04 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Boaz Harrosh, git
> -- David Jeske wrote:
>> - improve the man page description of "reset --hard"
>> - standardize all the potentially destructive operations
>> (after gc) on "-f/--force" to override
>
> The thing is 'force' is not always the most descriptive word
> for the behavior that you propose enabling with --force.
I'm not talking about switching "git reset --hard" to "git reset -f". I'm
talking about requiring a "-f" option to "git reset --hard" when it would
destroy or dangle information.
(a) If you have a clean working directory which is fully checked in and has
another branch tag other than the current branch tag, then "git reset --hard
<commitish>" is non-destructive, and would complete happily.
(b) If you have local modifications to working files it would complain "hey,
your working files are dirty, 'reset --hard' will blow them away, either revert
them or use -f". This is what Boaz asked for, and I doubt it would change along
would alter workflow much for people who are using "git reset --hard" to toss
attempted patches (since they were fully committed anyhow), or even undo a
clone or pull operation. If people use it as a combo "revert and reset", they
would notice.
(c) If the current location is only pointed to by the current branch (which you
are going to move with 'reset --hard') tell the user that those changes will be
dangling and will be eligible for garbage collection if they move the branch.
What to do in this case seems more controversial. I would prefer for this to
error with "either label these changes with 'branch', or use 'reset --hard -f'
to force us to leave these in the reflog unnamed". --- Some here say that
being in the reflog is enough, and the -f is overkill here. If we define
destructive as dropping code-commits, then that's true. If we define
destructive as leaving code-commits unreferenced, then -f is warranted.
Personally, I'd rather git help me avoid dropping the NAMES to tips, because
even with GC-never, I don't really want to find myself crawling through SHA1
hashes and visualization trees to find them later, when git could have reminded
me to name a branch that would conveniently show up in 'git branch'. It's easy
enough to avoid dropping the names, or force git to not care with '-f'. I
personally would like to avoid dealing with reflog or SHA1 hashes 99% of the
time.
> 'gc' is another command that has been mentioned along
> with its '--aggressive' option.
This was an accident. When I made my "mv --aggressive" joke I was NOT intending
to reference "gc --aggressive", that is just a coincidence. I was trying to
make up another 'semi-dangerous sounding name that might or not might be
destructive". It's comical that it's in use for gc. I don't see any
relationship between "gc --aggressive" and destructive behavior.
However, there IS a situation to require a "-f" on a, because again, "-f" would
be required for operations which destroy commits. If we think commits being in
the reflog is good enough to hold onto them, and users are thinking that items
being in the reflog are 'safe', then a GC where reflog entry expiration is
going to cause DAG entries to be removed could print an error like:
error: the following entries are beyond the expiration time,
...<base branchname>/<commit-ish>: 17 commits, 78 lines, 3 authors
...use diff <commit-ish> , to see the changes
...use gc -f, to cause them to be deleted
This wouldn't happen very often, and would make "gc" a safe operation even on
trees with shorter expiration time. In fact, if this were the way it worked, I
might set my GC back from never to "30 days", because this would not only allow
me to safely cleanup junk, but it would also allow me to catch unnamed and
dangling references before they became so old I didn't remember what to name
them.
This would make a "non forced gc" safe from throwing away commits, but still
make it really easy to do so for people who want to. Likewise, we could make
any "auto-gc" that happens not forced by default.
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 20:04 ` David Jeske
@ 2008-06-24 21:42 ` Brandon Casey
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l63P33FEDjCVQ0>
2008-06-24 22:54 ` Theodore Tso
2008-06-24 22:21 ` Steven Walter
1 sibling, 2 replies; 113+ messages in thread
From: Brandon Casey @ 2008-06-24 21:42 UTC (permalink / raw)
To: David Jeske; +Cc: Jakub Narebski, Boaz Harrosh, git
David Jeske wrote:
>> -- David Jeske wrote:
>>> - improve the man page description of "reset --hard"
>>> - standardize all the potentially destructive operations
>>> (after gc) on "-f/--force" to override
>> The thing is 'force' is not always the most descriptive word
>> for the behavior that you propose enabling with --force.
> I'm not talking about switching "git reset --hard" to "git reset -f". I'm
> talking about requiring a "-f" option to "git reset --hard" when it would
> destroy or dangle information.
I only have the same advice I gave to Boaz. I think you should try to adjust
your workflow so that 'git reset' is not necessary. It seems that for the
functions you're trying to perform, 'checkout' and 'branch' should be used rather
than 'reset'.
Again, as I mentioned to Boaz, there is really no benefit to reusing a single
branch name if that is what you are trying to do. The cost of branching in git
is 41 bytes i.e. nil. The cost of updating the working directory which happens
during the 'reset --hard' is exactly the same whether I do
'reset --hard <some_branch>' or 'checkout -b new_branch <some_branch>'.
In nearly every case where I, personally, have used 'reset --hard', I was using
it because I didn't care what the current state of the working directory or the
index were. They were wrong and I was resetting to the right state. I believe
this was the intended use for the command.
I'm not sure why you want to use reset so often. If there is something in the
documentation that led you to want to use reset maybe it can be changed so that
other users are not led in the same way.
About the reflog..
The reflog is not a storage area. It's just a log, like /var/log/messages. It is
there to provide a way to recover from mistakes. Mistakes are usually recognized
fairly quickly. If you have not realized that you have made a mistake after 30
days, it may be pretty hard to recover from since people have imperfect memories.
If we did not garbage collect the reflog it would just continue to grow appending
useless piece of information after useless piece of information.
-brandon
^ permalink raw reply [flat|nested] 113+ messages in thread[parent not found: <willow-jeske-01l5PFjPFEDjCfzf-01l63P33FEDjCVQ0>]
* Re: why is git destructive by default? (i suggest it not be!)
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l63P33FEDjCVQ0>
@ 2008-06-24 22:13 ` David Jeske
2008-06-24 22:13 ` David Jeske
1 sibling, 0 replies; 113+ messages in thread
From: David Jeske @ 2008-06-24 22:13 UTC (permalink / raw)
To: Brandon Casey; +Cc: Jakub Narebski, Boaz Harrosh, git
-- Brandon Casey wrote:
> I only have the same advice I gave to Boaz. I think you should try to adjust
> your workflow so that 'git reset' is not necessary. It seems that for the
> functions you're trying to perform, 'checkout' and 'branch' should be used
> rather than 'reset'.
Even when I change my workflow to avoid 'reset', I believe that the
user-interface of git will be stronger if it is a simpler expression of the
same functionality. One way to simplify it is to use convention that is
standardized across a set of tools so we don't have to learn every little
nuance of every little feature independently.
Two things I'd like to make it easy for users to never do are:
- delete data
- cause refs to be dangling
Therefore, I'd like a simple convention I can apply across all commands, so
that if users never do them, they'll never do either of the above things. I'm
not alone.
I think some of the impedance mismatch between my suggestions, and current
usage, has to do with where I'd like to be next. This is a meaty topic, I'll
start another thread on "policy and mechanism for less-connected clients".
> I'm not sure why you want to use reset so often. If there is something in the
> documentation that led you to want to use reset maybe it can be changed so
that
> other users are not led in the same way.
Yes, it's a problem in the git-gui and the "reset --hard" documentation. I'm
working on a patch.
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: why is git destructive by default? (i suggest it not be!)
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l63P33FEDjCVQ0>
2008-06-24 22:13 ` David Jeske
@ 2008-06-24 22:13 ` David Jeske
1 sibling, 0 replies; 113+ messages in thread
From: David Jeske @ 2008-06-24 22:13 UTC (permalink / raw)
To: Brandon Casey; +Cc: Jakub Narebski, Boaz Harrosh, git
-- Brandon Casey wrote:
> I only have the same advice I gave to Boaz. I think you should try to adjust
> your workflow so that 'git reset' is not necessary. It seems that for the
> functions you're trying to perform, 'checkout' and 'branch' should be used
> rather than 'reset'.
Even when I change my workflow to avoid 'reset', I believe that the
user-interface of git will be stronger if it is a simpler expression of the
same functionality. One way to simplify it is to use convention that is
standardized across a set of tools so we don't have to learn every little
nuance of every little feature independently.
Two things I'd like to make it easy for users to never do are:
- delete data
- cause refs to be dangling
Therefore, I'd like a simple convention I can apply across all commands, so
that if users never do them, they'll never do either of the above things. I'm
not alone.
I think some of the impedance mismatch between my suggestions, and current
usage, has to do with where I'd like to be next. This is a meaty topic, I'll
start another thread on "policy and mechanism for less-connected clients".
> I'm not sure why you want to use reset so often. If there is something in the
> documentation that led you to want to use reset maybe it can be changed so
that
> other users are not led in the same way.
Yes, it's a problem in the git-gui and the "reset --hard" documentation. I'm
working on a patch.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 21:42 ` Brandon Casey
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l63P33FEDjCVQ0>
@ 2008-06-24 22:54 ` Theodore Tso
2008-06-24 23:07 ` Junio C Hamano
1 sibling, 1 reply; 113+ messages in thread
From: Theodore Tso @ 2008-06-24 22:54 UTC (permalink / raw)
To: Brandon Casey; +Cc: David Jeske, Jakub Narebski, Boaz Harrosh, git
On Tue, Jun 24, 2008 at 04:42:49PM -0500, Brandon Casey wrote:
> Again, as I mentioned to Boaz, there is really no benefit to reusing
> a single branch name if that is what you are trying to do. The cost
> of branching in git is 41 bytes i.e. nil.
The main reason that I find for reusing a branch name is for my
integration branch. I have a script which basically does:
git checkout integration
git reset --hard origin
git merge branch-A
git merge branch-B
git merge branch-C
git merge branch-D
I suppose I could have avoided the use of git reset with something
like this:
git update-index --refresh --unmerged > /dev/null
if git diff-index --name-only HEAD | read dummy; then
echo "There are local changes; refusing to build integration branch!"
exit 1
fi
git update-ref refs/heads/integration origin
git checkout integration
git merge branch-A
git merge branch-B
git merge branch-C
git merge branch-D
Instead, I've just learned to be careful and my use of git reset
--hard is mainly for historical reasons. But the point is, I can very
easily think of workflows where it makes sense to reuse a branch name,
most of them having to do with creating integration branches which are
basically throwaways after I am done testing or building that combined
tree.
- Ted
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 22:54 ` Theodore Tso
@ 2008-06-24 23:07 ` Junio C Hamano
2008-06-25 2:26 ` Theodore Tso
0 siblings, 1 reply; 113+ messages in thread
From: Junio C Hamano @ 2008-06-24 23:07 UTC (permalink / raw)
To: Theodore Tso
Cc: Brandon Casey, David Jeske, Jakub Narebski, Boaz Harrosh, git
Theodore Tso <tytso@mit.edu> writes:
> The main reason that I find for reusing a branch name is for my
> integration branch. I have a script which basically does:
>
> git checkout integration
> git reset --hard origin
> git merge branch-A
> git merge branch-B
> git merge branch-C
> git merge branch-D
>
> I suppose I could have avoided the use of git reset with something
> like this:
>
> git update-index --refresh --unmerged > /dev/null
> if git diff-index --name-only HEAD | read dummy; then
> echo "There are local changes; refusing to build integration branch!"
> exit 1
> fi
> git update-ref refs/heads/integration origin
> git checkout integration
> git merge branch-A
> git merge branch-B
> git merge branch-C
> git merge branch-D
>
> Instead, I've just learned to be careful and my use of git reset
> --hard is mainly for historical reasons.
This makes it sound as if avoiding "reset --hard" is a good thing, but I
do not understand why.
The reason you have the diff-index check in the second sequence is because
update-ref does not have the "local changes" check either. You could have
used the same diff-index check in front of "reset --hard".
Moreover, in your original sequence above, doesn't "git checkout
integration" list your local changes when you have any, and wouldn't that
be a clue enough that the next "reset --hard origin" would discard them?
> ... But the point is, I can very
> easily think of workflows where it makes sense to reuse a branch name,
> most of them having to do with creating integration branches which are
> basically throwaways after I am done testing or building that combined
> tree.
Absolutely.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 23:07 ` Junio C Hamano
@ 2008-06-25 2:26 ` Theodore Tso
2008-06-25 8:58 ` Jakub Narebski
2008-06-26 15:13 ` Brandon Casey
0 siblings, 2 replies; 113+ messages in thread
From: Theodore Tso @ 2008-06-25 2:26 UTC (permalink / raw)
To: Junio C Hamano
Cc: Brandon Casey, David Jeske, Jakub Narebski, Boaz Harrosh, git
On Tue, Jun 24, 2008 at 04:07:57PM -0700, Junio C Hamano wrote:
> > Instead, I've just learned to be careful and my use of git reset
> > --hard is mainly for historical reasons.
>
> This makes it sound as if avoiding "reset --hard" is a good thing, but I
> do not understand why.
Well, it was Brandon Casey who was asserting that git reset --hard was
evil, which I generally don't agree with. I do use workflows that use
it a fair amount, usually because its more convenient to type "git
checkout <foo>; git reset --hard <baz>" than something involving "git
update-ref refs/heads/<foo> <baz>". The former has more characters
than the latter, and involves more disk I/O since it mutates the
working directory; but it's something about needing to type
"refs/heads/" such that I generally tend to type "git checkout....
git reset". I can't explain why; maybe it's just psychological.
The reason why I've been thinking that I should change my shell script
from:
git checkout integration
git reset --hard <foo>
to:
git update-ref ref/heads/integration HEAD
git checkout integration
Is actually because the first tends to touch more files in the working
directory than the second (because if the integration branch is a week
or two old, the git checkout unwinds the global state by two weeks,
and then the git reset --hard has to bring the state back up to
recentcy; the second generally involves a smaller set of files
changing). That's a very minor point, granted.
> The reason you have the diff-index check in the second sequence is because
> update-ref does not have the "local changes" check either. You could have
> used the same diff-index check in front of "reset --hard".
Definitely true. The reason why I don't have this check is because
I'm generally careful and I run a "git stat" to make sure there are no
local changes in the tree before I run the script.
> Moreover, in your original sequence above, doesn't "git checkout
> integration" list your local changes when you have any, and wouldn't that
> be a clue enough that the next "reset --hard origin" would discard them?
... because it's in a shell script; being fundamentally lazy, instead
of typing that sequence over and over again, I've scripted it. :-)
- Ted
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
2008-06-25 2:26 ` Theodore Tso
@ 2008-06-25 8:58 ` Jakub Narebski
2008-06-25 9:14 ` Junio C Hamano
2008-06-26 15:13 ` Brandon Casey
1 sibling, 1 reply; 113+ messages in thread
From: Jakub Narebski @ 2008-06-25 8:58 UTC (permalink / raw)
To: Theodore Tso
Cc: Junio C Hamano, Brandon Casey, David Jeske, Boaz Harrosh, git
On Wed, 25 Jun 2008, Theodore Tso wrote:
> The reason why I've been thinking that I should change my shell script
> from:
>
> git checkout integration
> git reset --hard <foo>
>
> to:
>
> git update-ref ref/heads/integration HEAD
> git checkout integration
Hmmmm.... Wouldn't it be easier on fingers to use
git reset --soft integration
--
Jakub Narebski
Poland
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: why is git destructive by default? (i suggest it not be!)
2008-06-25 8:58 ` Jakub Narebski
@ 2008-06-25 9:14 ` Junio C Hamano
0 siblings, 0 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 9:14 UTC (permalink / raw)
To: Jakub Narebski
Cc: Theodore Tso, Brandon Casey, David Jeske, Boaz Harrosh, git
Jakub Narebski <jnareb@gmail.com> writes:
> On Wed, 25 Jun 2008, Theodore Tso wrote:
>
>> The reason why I've been thinking that I should change my shell script
>> from:
>>
>> git checkout integration
>> git reset --hard <foo>
>>
>> to:
>>
>> git update-ref ref/heads/integration HEAD
>> git checkout integration
>
> Hmmmm.... Wouldn't it be easier on fingers to use
>
> git reset --soft integration
That does not do anything close to what Ted is doing, does it?
Anyway, here is how I conclude my git day:
git checkout next
... merge more and test
... be happy that next is in very good shape ;-)
git branch -f pu
git checkout pu
git merge ... merge other topics to rebuild pu
git merge ...
...
which is probably a bit less error prone then update-ref, if you type from
the command line like I do.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
2008-06-25 2:26 ` Theodore Tso
2008-06-25 8:58 ` Jakub Narebski
@ 2008-06-26 15:13 ` Brandon Casey
1 sibling, 0 replies; 113+ messages in thread
From: Brandon Casey @ 2008-06-26 15:13 UTC (permalink / raw)
To: Theodore Tso
Cc: Junio C Hamano, David Jeske, Jakub Narebski, Boaz Harrosh, git
Theodore Tso wrote:
> On Tue, Jun 24, 2008 at 04:07:57PM -0700, Junio C Hamano wrote:
>>> Instead, I've just learned to be careful and my use of git reset
>>> --hard is mainly for historical reasons.
>> This makes it sound as if avoiding "reset --hard" is a good thing, but I
>> do not understand why.
>
> Well, it was Brandon Casey who was asserting that git reset --hard was
> evil, which I generally don't agree with.
I definitely don't think 'reset --hard' is evil. I _do_ think it is somewhat
of an advanced command. It should be used where it is appropriate. I think
it is a misuse of the command if it is used in place of checkout, which I got
the impression might be the case.
You described resetting an integration branch, Junio does a similar thing
with pu and these are both valid uses. This is what I was talking about
when I said that usually when I use reset I don't care about the state of
the branch I am resetting. I also agree there are many other valid uses for
'git reset --hard'.
-brandon
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 20:04 ` David Jeske
2008-06-24 21:42 ` Brandon Casey
@ 2008-06-24 22:21 ` Steven Walter
2008-06-24 22:21 ` [PATCH] cmd_reset: don't trash uncommitted changes unless told to Steven Walter
1 sibling, 1 reply; 113+ messages in thread
From: Steven Walter @ 2008-06-24 22:21 UTC (permalink / raw)
To: David Jeske; +Cc: Jakub Narebski, Boaz Harrosh, git
On Tue, Jun 24, 2008 at 08:04:30PM -0000, David Jeske wrote:
> I'm not talking about switching "git reset --hard" to "git reset -f". I'm
> talking about requiring a "-f" option to "git reset --hard" when it would
> destroy or dangle information.
I think you're asking for something like the following...
--
-Steven Walter <stevenrwalter@gmail.com>
Freedom is the freedom to say that 2 + 2 = 4
B2F1 0ECC E605 7321 E818 7A65 FC81 9777 DC28 9E8F
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-24 22:21 ` Steven Walter
@ 2008-06-24 22:21 ` Steven Walter
2008-06-24 22:31 ` Junio C Hamano
2008-06-25 5:29 ` Johannes Gilger
0 siblings, 2 replies; 113+ messages in thread
From: Steven Walter @ 2008-06-24 22:21 UTC (permalink / raw)
To: git, jeske; +Cc: Steven Walter
Give "reset --hard" a -f (force) flag, without which it will refuse to
proceed if there are changes in the index or working tree.
Signed-off-by: Steven Walter <stevenrwalter@gmail.com>
---
builtin-reset.c | 24 +++++++++++++++++++++++-
1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/builtin-reset.c b/builtin-reset.c
index f34acb1..6ee8448 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -11,8 +11,10 @@
#include "tag.h"
#include "object.h"
#include "commit.h"
+#include "diff.h"
#include "run-command.h"
#include "refs.h"
+#include "revision.h"
#include "diff.h"
#include "diffcore.h"
#include "tree.h"
@@ -165,12 +167,26 @@ static void prepend_reflog_action(const char *action, char *buf, size_t size)
warning("Reflog action message too long: %.*s...", 50, buf);
}
+/* Stolen from builtin-revert.c... */
+static int index_is_dirty(void)
+{
+ struct rev_info rev;
+ read_cache();
+ init_revisions(&rev, NULL);
+ setup_revisions(0, NULL, &rev, "HEAD");
+ DIFF_OPT_SET(&rev.diffopt, QUIET);
+ DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);
+ run_diff_files(&rev, 1);
+ return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES);
+}
+
enum reset_type { MIXED, SOFT, HARD, NONE };
static const char *reset_type_names[] = { "mixed", "soft", "hard", NULL };
int cmd_reset(int argc, const char **argv, const char *prefix)
{
- int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0;
+ int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0,
+ force = 0;
const char *rev = "HEAD";
unsigned char sha1[20], *orig = NULL, sha1_orig[20],
*old_orig = NULL, sha1_old_orig[20];
@@ -184,6 +200,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
"reset HEAD, index and working tree", HARD),
OPT_BOOLEAN('q', NULL, &quiet,
"disable showing new HEAD in hard reset and progress message"),
+ OPT_BOOLEAN('f', NULL, &force,
+ "proceed even if there are uncommitted changes"),
OPT_END()
};
@@ -225,6 +243,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
if (reset_type == HARD && is_bare_repository())
die("hard reset makes no sense in a bare repository");
+ if (reset_type == HARD && !force && index_is_dirty()) {
+ die("Uncommitted changes; re-run with -f to trash them");
+ }
+
/* Soft reset does not touch the index file nor the working tree
* at all, but requires them in a good order. Other resets reset
* the index file to the tree object we are switching to. */
--
1.5.6.dirty
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-24 22:21 ` [PATCH] cmd_reset: don't trash uncommitted changes unless told to Steven Walter
@ 2008-06-24 22:31 ` Junio C Hamano
2008-06-25 9:12 ` Boaz Harrosh
2008-06-25 5:29 ` Johannes Gilger
1 sibling, 1 reply; 113+ messages in thread
From: Junio C Hamano @ 2008-06-24 22:31 UTC (permalink / raw)
To: Steven Walter; +Cc: git, jeske
Steven Walter <stevenrwalter@gmail.com> writes:
> @@ -225,6 +243,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
> if (reset_type == HARD && is_bare_repository())
> die("hard reset makes no sense in a bare repository");
>
> + if (reset_type == HARD && !force && index_is_dirty()) {
> + die("Uncommitted changes; re-run with -f to trash them");
> + }
> +
Please don't. With your change, does the testsuite even pass?
"reset --hard" has *ALWAYS* meant to be destructive --- discarding
potential local cruft is the whole point of the operation.
Learn the lingo, and get over it.
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-24 22:31 ` Junio C Hamano
@ 2008-06-25 9:12 ` Boaz Harrosh
2008-06-25 9:23 ` Junio C Hamano
` (3 more replies)
0 siblings, 4 replies; 113+ messages in thread
From: Boaz Harrosh @ 2008-06-25 9:12 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Steven Walter, git, jeske
Junio C Hamano wrote:
> Steven Walter <stevenrwalter@gmail.com> writes:
>
>> @@ -225,6 +243,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
>> if (reset_type == HARD && is_bare_repository())
>> die("hard reset makes no sense in a bare repository");
>>
>> + if (reset_type == HARD && !force && index_is_dirty()) {
>> + die("Uncommitted changes; re-run with -f to trash them");
>> + }
>> +
>
> Please don't. With your change, does the testsuite even pass?
>
> "reset --hard" has *ALWAYS* meant to be destructive --- discarding
> potential local cruft is the whole point of the operation.
>
I was under the impression that --hard means working-directory-also
as opposed to tree-and-index-only. Nothing to do with
destructive-discarding. If it is then something is missing.
I need 2 distinct functions. You combine to functions under
one command.
> Learn the lingo, and get over it.
>
I did lern the lingo and got bitten. I wanted to do one thing
also got the other one.
there is:
git-reset --clean - destructive-discarding any local changes
git-reset --hard - move tree index and working directory to new head
How can I separate between them, Please
Boaz
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 9:12 ` Boaz Harrosh
@ 2008-06-25 9:23 ` Junio C Hamano
2008-06-25 9:59 ` Boaz Harrosh
2008-06-25 10:16 ` Johannes Schindelin
` (2 subsequent siblings)
3 siblings, 1 reply; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 9:23 UTC (permalink / raw)
To: Boaz Harrosh; +Cc: Steven Walter, git, jeske
Boaz Harrosh <bharrosh@panasas.com> writes:
> Junio C Hamano wrote:
>
>> "reset --hard" has *ALWAYS* meant to be destructive --- discarding
>> potential local cruft is the whole point of the operation.
>
> I was under the impression that --hard means working-directory-also
> as opposed to tree-and-index-only. Nothing to do with
> destructive-discarding.
Then you should revise your impression, as it is simply *WRONG*. When
I say something about history of git, I know what I am talking about ;-)
Reset has been about nuking local changes from the very beginning. That
is why it removes MERGE_HEAD, rr-cache/MERGE_RR as well as removing
conflicted stages in the index and reverts local changes from the worktree.
It is "my worktree state is a mess, and I cannot even describe nor care
which paths are dirty --- just get rid of the local changes so that I can
start working cleanly from a checkout of HEAD".
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 9:23 ` Junio C Hamano
@ 2008-06-25 9:59 ` Boaz Harrosh
0 siblings, 0 replies; 113+ messages in thread
From: Boaz Harrosh @ 2008-06-25 9:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Steven Walter, git, jeske
Junio C Hamano wrote:
> Boaz Harrosh <bharrosh@panasas.com> writes:
>
>> Junio C Hamano wrote:
>>
>>> "reset --hard" has *ALWAYS* meant to be destructive --- discarding
>>> potential local cruft is the whole point of the operation.
>> I was under the impression that --hard means working-directory-also
>> as opposed to tree-and-index-only. Nothing to do with
>> destructive-discarding.
>
> Then you should revise your impression, as it is simply *WRONG*. When
> I say something about history of git, I know what I am talking about ;-)
>
> Reset has been about nuking local changes from the very beginning. That
> is why it removes MERGE_HEAD, rr-cache/MERGE_RR as well as removing
> conflicted stages in the index and reverts local changes from the worktree.
>
> It is "my worktree state is a mess, and I cannot even describe nor care
> which paths are dirty --- just get rid of the local changes so that I can
> start working cleanly from a checkout of HEAD".
OK Thanks, I see.
I have made myself that git-move-head script that uses checkouts and
renames so I guess I'm happy. I used to use the --hard as a shortcut.
Boaz
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 9:12 ` Boaz Harrosh
2008-06-25 9:23 ` Junio C Hamano
@ 2008-06-25 10:16 ` Johannes Schindelin
2008-06-25 10:24 ` Matthias Kestenholz
2008-06-25 10:41 ` [PATCH] cmd_reset: don't trash uncommitted changes unless told to Johannes Sixt
2008-06-25 13:19 ` Ian Hilt
2008-06-26 5:31 ` Andreas Ericsson
3 siblings, 2 replies; 113+ messages in thread
From: Johannes Schindelin @ 2008-06-25 10:16 UTC (permalink / raw)
To: Boaz Harrosh; +Cc: Junio C Hamano, Steven Walter, git, jeske
Hi,
just to add to Junio's comments:
On Wed, 25 Jun 2008, Boaz Harrosh wrote:
> Junio C Hamano wrote:
> > Steven Walter <stevenrwalter@gmail.com> writes:
> >
> >> @@ -225,6 +243,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
> >> if (reset_type == HARD && is_bare_repository())
> >> die("hard reset makes no sense in a bare repository");
> >>
> >> + if (reset_type == HARD && !force && index_is_dirty()) {
> >> + die("Uncommitted changes; re-run with -f to trash them");
> >> + }
> >> +
> >
> > Please don't. With your change, does the testsuite even pass?
> >
> > "reset --hard" has *ALWAYS* meant to be destructive --- discarding
> > potential local cruft is the whole point of the operation.
> >
>
> I was under the impression that --hard means working-directory-also
> as opposed to tree-and-index-only. Nothing to do with
> destructive-discarding.
But "reset" _means_ to discard something.
Frankly, we could introduce "git reset --hard --force --really
--really-i-mean-it --do-reset-the-fscking-working-directory-NOW", but I do
not think that it makes sense.
If you want to reset the working directory, you want to reset the working
directory. If you wanted to save the changes somewhere, you should have
done that. We have enough ways to do that.
> > Learn the lingo, and get over it.
>
> I did lern the lingo and got bitten.
Apparently not. So again, "reset --hard" means to reset HEAD, index and
working directory to the revision you pass (defaulting to the HEAD).
The fact that you do not lose the information which used to be HEAD, is
just a side-effect of Git storing all the revisions in one big graph. It
is _not_ implied by "reset", which, as I pointed out, means "re-set".
> there is:
> git-reset --clean - destructive-discarding any local changes
What would be a "nondestructive-discarding", /me wonders.
> git-reset --hard - move tree index and working directory to new head
That is not "git reset --hard".
"move" to a new head is called "switching branches" in Git lingo (and BTW
in many other SCM lingos, too, so you might just as well get used to it),
and it is another command: "git checkout <branch>".
Incidentally, a friend just told me that "checkout" is everything but
intuitive, and he would have preferred "git branch switch <branch>", but
then settled for my proposed "git branch --switch <branch>", which I did
not have time to implement yet, unfortunately.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 10:16 ` Johannes Schindelin
@ 2008-06-25 10:24 ` Matthias Kestenholz
2008-06-25 10:46 ` Anton Gladkov
2008-06-25 10:41 ` [PATCH] cmd_reset: don't trash uncommitted changes unless told to Johannes Sixt
1 sibling, 1 reply; 113+ messages in thread
From: Matthias Kestenholz @ 2008-06-25 10:24 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Boaz Harrosh, Junio C Hamano, Steven Walter, git, jeske
On Wed, 2008-06-25 at 11:16 +0100, Johannes Schindelin wrote:
> Incidentally, a friend just told me that "checkout" is everything but
> intuitive, and he would have preferred "git branch switch <branch>", but
> then settled for my proposed "git branch --switch <branch>", which I did
> not have time to implement yet, unfortunately.
But why? I don't want to 'branch', I want to 'checkout' another branch,
which incidentally matches the git command I need to use to achieve
that.
Matthias
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 10:24 ` Matthias Kestenholz
@ 2008-06-25 10:46 ` Anton Gladkov
2008-06-25 12:33 ` Johannes Schindelin
2008-06-25 14:49 ` [PATCH] cmd_reset: don't trash uncommitted changes unless toldto Craig L. Ching
0 siblings, 2 replies; 113+ messages in thread
From: Anton Gladkov @ 2008-06-25 10:46 UTC (permalink / raw)
To: Matthias Kestenholz
Cc: Johannes Schindelin, Boaz Harrosh, Junio C Hamano, Steven Walter,
git@vger.kernel.org, jeske@google.com
On Wed, Jun 25, 2008 at 02:24:58PM +0400, Matthias Kestenholz wrote:
> On Wed, 2008-06-25 at 11:16 +0100, Johannes Schindelin wrote:
> > Incidentally, a friend just told me that "checkout" is everything but
> > intuitive, and he would have preferred "git branch switch <branch>", but
> > then settled for my proposed "git branch --switch <branch>", which I did
> > not have time to implement yet, unfortunately.
>
> But why? I don't want to 'branch', I want to 'checkout' another branch,
> which incidentally matches the git command I need to use to achieve
> that.
Because 'checkout' in other SCMs like CVS or SVN means 'get latest data from
repo', i.e. it acts like 'pull' or 'fetch' in git.
And 'branch' means branch manipulation: creating, deleting, switching...
--
Best regards,
Anton
mailto:agladkov@parallels.com
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 10:46 ` Anton Gladkov
@ 2008-06-25 12:33 ` Johannes Schindelin
2008-06-25 14:49 ` [PATCH] cmd_reset: don't trash uncommitted changes unless toldto Craig L. Ching
1 sibling, 0 replies; 113+ messages in thread
From: Johannes Schindelin @ 2008-06-25 12:33 UTC (permalink / raw)
To: Anton Gladkov
Cc: Matthias Kestenholz, Boaz Harrosh, Junio C Hamano, Steven Walter,
git@vger.kernel.org, jeske@google.com
Hi,
On Wed, 25 Jun 2008, Anton Gladkov wrote:
> On Wed, Jun 25, 2008 at 02:24:58PM +0400, Matthias Kestenholz wrote:
> > On Wed, 2008-06-25 at 11:16 +0100, Johannes Schindelin wrote:
> > > Incidentally, a friend just told me that "checkout" is everything but
> > > intuitive, and he would have preferred "git branch switch <branch>", but
> > > then settled for my proposed "git branch --switch <branch>", which I did
> > > not have time to implement yet, unfortunately.
> >
> > But why? I don't want to 'branch', I want to 'checkout' another branch,
> > which incidentally matches the git command I need to use to achieve
> > that.
>
> Because 'checkout' in other SCMs like CVS or SVN means 'get latest data
> from repo', i.e. it acts like 'pull' or 'fetch' in git. And 'branch'
> means branch manipulation: creating, deleting, switching...
Actually, I don't find this a good reason at all. The fact that other
SCMs bastardized a term to mean something it clearly does not mean, is
irrelevant here.
The thing is: if we say "let's switch branches", what command would spring
to mind to a (non-CVS-braindamaged) user? Exactly: "git branch". That is
the command that should do something with branches.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 113+ messages in thread
* RE: [PATCH] cmd_reset: don't trash uncommitted changes unless toldto
2008-06-25 10:46 ` Anton Gladkov
2008-06-25 12:33 ` Johannes Schindelin
@ 2008-06-25 14:49 ` Craig L. Ching
2008-06-25 15:18 ` Anton Gladkov
1 sibling, 1 reply; 113+ messages in thread
From: Craig L. Ching @ 2008-06-25 14:49 UTC (permalink / raw)
To: Anton Gladkov, Matthias Kestenholz
Cc: Johannes Schindelin, Boaz Harrosh, Junio C Hamano, Steven Walter,
git, jeske
> -----Original Message-----
> From: git-owner@vger.kernel.org
> [mailto:git-owner@vger.kernel.org] On Behalf Of Anton Gladkov
> Sent: Wednesday, June 25, 2008 5:46 AM
> To: Matthias Kestenholz
> Cc: Johannes Schindelin; Boaz Harrosh; Junio C Hamano; Steven
> Walter; git@vger.kernel.org; jeske@google.com
> Subject: Re: [PATCH] cmd_reset: don't trash uncommitted
> changes unless toldto
>
> Because 'checkout' in other SCMs like CVS or SVN means 'get
> latest data from repo', i.e. it acts like 'pull' or 'fetch' in git.
> And 'branch' means branch manipulation: creating, deleting,
> switching...
>
Checkout, for me and a lot of people I work with, never meant "get
latest data from repo", it always meant "get me a workspace". Anyway,
just sharing a dissenting opinion, I don't agree that the checkout verb
is used incorrectly in git.
> --
> Best regards,
> Anton
> mailto:agladkov@parallels.com
> --
Cheers,
Craig
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless toldto
2008-06-25 14:49 ` [PATCH] cmd_reset: don't trash uncommitted changes unless toldto Craig L. Ching
@ 2008-06-25 15:18 ` Anton Gladkov
0 siblings, 0 replies; 113+ messages in thread
From: Anton Gladkov @ 2008-06-25 15:18 UTC (permalink / raw)
To: Craig L. Ching
Cc: Matthias Kestenholz, Johannes Schindelin, Boaz Harrosh,
Junio C Hamano, Steven Walter, git@vger.kernel.org,
jeske@google.com
On Wed, Jun 25, 2008 at 06:49:16PM +0400, Craig L. Ching wrote:
> > Because 'checkout' in other SCMs like CVS or SVN means 'get
> > latest data from repo', i.e. it acts like 'pull' or 'fetch' in git.
> > And 'branch' means branch manipulation: creating, deleting,
> > switching...
> >
> Checkout, for me and a lot of people I work with, never meant "get
> latest data from repo", it always meant "get me a workspace". Anyway,
> just sharing a dissenting opinion, I don't agree that the checkout verb
> is used incorrectly in git.
Craig,
I'm not trying to say that git incorrectly uses 'checkout' word :)
--
Best regards,
Anton
mailto:agladkov@parallels.com
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 10:16 ` Johannes Schindelin
2008-06-25 10:24 ` Matthias Kestenholz
@ 2008-06-25 10:41 ` Johannes Sixt
2008-06-25 12:38 ` Johannes Schindelin
1 sibling, 1 reply; 113+ messages in thread
From: Johannes Sixt @ 2008-06-25 10:41 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Boaz Harrosh, Junio C Hamano, Steven Walter, git, jeske
Johannes Schindelin schrieb:
> Incidentally, a friend just told me that "checkout" is everything but
> intuitive, and he would have preferred "git branch switch <branch>", but
> then settled for my proposed "git branch --switch <branch>", which I did
> not have time to implement yet, unfortunately.
$ git config alias.switch checkout
$ git switch topic
Hm? Notice that the command even reports back:
Switched to branch "topic"
^^^^^^^^
-- Hannes
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 10:41 ` [PATCH] cmd_reset: don't trash uncommitted changes unless told to Johannes Sixt
@ 2008-06-25 12:38 ` Johannes Schindelin
2008-06-25 13:51 ` Theodore Tso
0 siblings, 1 reply; 113+ messages in thread
From: Johannes Schindelin @ 2008-06-25 12:38 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Boaz Harrosh, Junio C Hamano, Steven Walter, git, jeske
Hi,
On Wed, 25 Jun 2008, Johannes Sixt wrote:
> Johannes Schindelin schrieb:
> > Incidentally, a friend just told me that "checkout" is everything but
> > intuitive, and he would have preferred "git branch switch <branch>", but
> > then settled for my proposed "git branch --switch <branch>", which I did
> > not have time to implement yet, unfortunately.
>
> $ git config alias.switch checkout
> $ git switch topic
>
> Hm? Notice that the command even reports back:
>
> Switched to branch "topic"
> ^^^^^^^^
Nice. And now my friend says "why does this braindamaged Git not have
that command by _default_? Hmm? It is _just as braindamaged_ as CVS!"
And I would not have anything reasonable for my defense.
Because Git _should_ have an intuitive command to switch branches by
default. "git checkout" just does not fly, especially given that it can
be used to revert single files (which "git revert" should know how to, but
does not, see
http://mid.gmane.org/7vlk8wshii.fsf@gitster.siamese.dyndns.org).
I _do_ see a cause of confusion here, _even_ if I know Git pretty well.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 12:38 ` Johannes Schindelin
@ 2008-06-25 13:51 ` Theodore Tso
2008-06-25 17:22 ` Junio C Hamano
2008-06-26 12:01 ` Matthieu Moy
0 siblings, 2 replies; 113+ messages in thread
From: Theodore Tso @ 2008-06-25 13:51 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Johannes Sixt, Boaz Harrosh, Junio C Hamano, Steven Walter, git,
jeske
On Wed, Jun 25, 2008 at 01:38:30PM +0100, Johannes Schindelin wrote:
> > $ git config alias.switch checkout
> > $ git switch topic
> >
> > Hm? Notice that the command even reports back:
> >
> > Switched to branch "topic"
> > ^^^^^^^^
>
> Nice. And now my friend says "why does this braindamaged Git not have
> that command by _default_? Hmm? It is _just as braindamaged_ as CVS!"
I agree that "git switch" would be a great alias to have for "git
checkout". It is much more intuitive; traditionally, the issue has
always been that it's not so intuitive for existing git users, who
have gotten used to the existing quirks, and it people won't want to
break things for the existing users. (There are analogues to this is
the English language --- why is it that "though", "through", "plough",
"cough", "hough", or "tough" don't rhyme[1]?)
[1] http://www.mipmip.org/tidbits/pronunciation.shtml
> And I would not have anything reasonable for my defense.
Neither does the English language; but just try changing it!
"Historical reasons" is for better or for worse a very strong
argument.
> Because Git _should_ have an intuitive command to switch branches by
> default. "git checkout" just does not fly, especially given that it can
> be used to revert single files (which "git revert" should know how to, but
> does not, see
> http://mid.gmane.org/7vlk8wshii.fsf@gitster.siamese.dyndns.org).
I used to argue for this, but gave up, because no one seemed to agree
with me. So now I just have the following in
/home/tytso/bin/git-revert-file and I am very happy:
#!/bin/sh
#
prefix=$(git rev-parse --show-prefix)
for i in $*
do
git show HEAD:$prefix$i > $i
done
It makes "git revert-file <file1> <file2> <file3>" do the right thing.
Yeah, it doesn't do enough error checking, and it doesn't handle
filenames with spaces, and there are probably other corner cases it
doesn't get right, but it's been enough to keep me happy. :-)
If someone wants to take the above and turn it into git-rename.sh and
try to submit it to the git tree --- they are welcome to do it. Or
heck, if Junio is willing to commit that it that with the appropriate
cleanups it would be accepted, I'd be willing to do the work. I just
got tired of arguing that the concept of "git revert-file" was in fact
useful, and so its existence could be justified, which IIRC was
disputed the last time we went around this topic. I know I wanted it,
though, so I implemented it for myself.
> I _do_ see a cause of confusion here, _even_ if I know Git pretty well.
As do I.... I think the expert git users have just leared how to work
around it, either by learning the non-linearities in the UI, or by our
own private hacks or aliases.
- Ted
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 13:51 ` Theodore Tso
@ 2008-06-25 17:22 ` Junio C Hamano
2008-06-25 19:50 ` Theodore Tso
2008-06-26 11:55 ` Björn Steinbrink
2008-06-26 12:01 ` Matthieu Moy
1 sibling, 2 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 17:22 UTC (permalink / raw)
To: Theodore Tso
Cc: Johannes Schindelin, Johannes Sixt, Boaz Harrosh, Steven Walter,
git, jeske
Theodore Tso <tytso@mit.edu> writes:
> I used to argue for this, but gave up, because no one seemed to agree
> with me. So now I just have the following in
> /home/tytso/bin/git-revert-file and I am very happy:
>
> #!/bin/sh
> #
> prefix=$(git rev-parse --show-prefix)
>
> for i in $*
> do
> git show HEAD:$prefix$i > $i
> done
Isn't that this?
#!/bin/sh
exec git checkout HEAD -- "$@"
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 17:22 ` Junio C Hamano
@ 2008-06-25 19:50 ` Theodore Tso
2008-06-25 20:04 ` Avery Pennarun
2008-06-25 20:09 ` Junio C Hamano
2008-06-26 11:55 ` Björn Steinbrink
1 sibling, 2 replies; 113+ messages in thread
From: Theodore Tso @ 2008-06-25 19:50 UTC (permalink / raw)
To: Junio C Hamano
Cc: Johannes Schindelin, Johannes Sixt, Boaz Harrosh, Steven Walter,
git, jeske
On Wed, Jun 25, 2008 at 10:22:08AM -0700, Junio C Hamano wrote:
> Isn't that this?
>
> #!/bin/sh
> exec git checkout HEAD -- "$@"
Well, I think you really want this to handle filenames with spaces:
for i in $*
do
git checkout HEAD -- "$i"
done
I still think it would be nice this as a built-in for "git
revert-file" since this is much easier to type than "git checkout HEAD
-- " (all those characters and capital letters). But if it ends up
being a private shell script for people who do this a lot, that's also fine.
I will say that it was not at all obvious that "git checkout" can also
be used to revert files, so it wasn't one of the man pages that looked
for when trying to figure out how to implement revert files. That's
why I ended up using:
git show HEAD:$prefix$i > $i
- Ted
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 19:50 ` Theodore Tso
@ 2008-06-25 20:04 ` Avery Pennarun
2008-06-25 20:11 ` Junio C Hamano
2008-06-25 20:38 ` Theodore Tso
2008-06-25 20:09 ` Junio C Hamano
1 sibling, 2 replies; 113+ messages in thread
From: Avery Pennarun @ 2008-06-25 20:04 UTC (permalink / raw)
To: Theodore Tso
Cc: Junio C Hamano, Johannes Schindelin, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
On 6/25/08, Theodore Tso <tytso@mit.edu> wrote:
> On Wed, Jun 25, 2008 at 10:22:08AM -0700, Junio C Hamano wrote:
> > exec git checkout HEAD -- "$@"
>
> Well, I think you really want this to handle filenames with spaces:
>
> for i in $*
> do
> git checkout HEAD -- "$i"
> done
"$@" notation actually handles spaces just fine. It's magic that way.
On the other hand, "for i in $*" does not, because all the spaces get
split as part of the unquoted $* in "for". Beware!
> I still think it would be nice this as a built-in for "git
> revert-file" since this is much easier to type than "git checkout HEAD
> -- " (all those characters and capital letters). But if it ends up
> being a private shell script for people who do this a lot, that's also fine.
How about making "git checkout" default to HEAD if no revision is
supplied? There's precedent for this in, say, git-diff (and I think a
few others).
Incidentally, "checkout <filename>" was also the way to do a revert
operation in CVS. And the way to switch branches, too, iirc. So git
isn't being too unusual here. That said, the commands were
deliberately renamed in svn because CVS was considered largely insane.
Have fun,
Avery
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:04 ` Avery Pennarun
@ 2008-06-25 20:11 ` Junio C Hamano
2008-06-25 20:22 ` Avery Pennarun
2008-06-25 20:37 ` Steven Walter
2008-06-25 20:38 ` Theodore Tso
1 sibling, 2 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 20:11 UTC (permalink / raw)
To: Avery Pennarun
Cc: Theodore Tso, Junio C Hamano, Johannes Schindelin, Johannes Sixt,
Boaz Harrosh, Steven Walter, git, jeske
"Avery Pennarun" <apenwarr@gmail.com> writes:
> How about making "git checkout" default to HEAD if no revision is
> supplied? There's precedent for this in, say, git-diff (and I think a
> few others).
Won't fly. 'git checkout -- "$@"' is to revert to the last staged
version.
* You say "git checkout branch" when you want to "check out that branch";
* You say "git checkout -- file" when you want to "check out the file
from the index";
* You say "git checkout v1.5 -- file" when you want to "check out the
file out of that revision".
It's not that hard.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:11 ` Junio C Hamano
@ 2008-06-25 20:22 ` Avery Pennarun
2008-06-25 20:48 ` Junio C Hamano
2008-06-25 20:37 ` Steven Walter
1 sibling, 1 reply; 113+ messages in thread
From: Avery Pennarun @ 2008-06-25 20:22 UTC (permalink / raw)
To: Junio C Hamano
Cc: Theodore Tso, Johannes Schindelin, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
On 6/25/08, Junio C Hamano <gitster@pobox.com> wrote:
> "Avery Pennarun" <apenwarr@gmail.com> writes:
>
> > How about making "git checkout" default to HEAD if no revision is
> > supplied? There's precedent for this in, say, git-diff (and I think a
> > few others).
>
> Won't fly. 'git checkout -- "$@"' is to revert to the last staged
> version.
Ah, I didn't catch the difference between HEAD and index there.
> * You say "git checkout -- file" when you want to "check out the file
> from the index";
The real question here is the --. Is it strictly needed? It's
optional in things like git-diff, which just do their best to guess
what you mean if you don't use the --.
If reset and checkout made the -- optional, then you could do:
git reset filename # undo an accidental "add"
git checkout filename # undo accidental modifications that haven't been added
...and save git reset --hard for people willing to take that risk.
(The fact that git-gui includes git reset --hard as a really
easy-to-click GUI command scared me the first time I saw it, too.)
I think simplifying the syntax might help to make the role of the
index less mysterious in the whole "revert" operation. It's not
obvious to me at all whether a revert-file ought to get the one from
HEAD or the one from the index. But I can easily understand and
explain checkout (copy index to working copy) and reset (undo an add).
Thanks,
Avery
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:22 ` Avery Pennarun
@ 2008-06-25 20:48 ` Junio C Hamano
2008-06-25 20:58 ` Avery Pennarun
0 siblings, 1 reply; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 20:48 UTC (permalink / raw)
To: Avery Pennarun
Cc: Junio C Hamano, Theodore Tso, Johannes Schindelin, Johannes Sixt,
Boaz Harrosh, Steven Walter, git, jeske
"Avery Pennarun" <apenwarr@gmail.com> writes:
>> * You say "git checkout -- file" when you want to "check out the file
>> from the index";
>
> The real question here is the --. Is it strictly needed? It's
> optional in things like git-diff, which just do their best to guess
> what you mean if you don't use the --.
No, I wrote -- only for clarity, because you can happen to have a branch
whose name is the same as the file. Otherwise you can safely omit it,
just like git-diff and any other commands that follow the -- convention.
I have a work tree that has an untracked file HEAD and master just to
catch script breakages that forgets to place -- in appropriate places when
they deal with user supplied pathnames.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:48 ` Junio C Hamano
@ 2008-06-25 20:58 ` Avery Pennarun
2008-06-25 21:24 ` Re* " Junio C Hamano
0 siblings, 1 reply; 113+ messages in thread
From: Avery Pennarun @ 2008-06-25 20:58 UTC (permalink / raw)
To: Junio C Hamano
Cc: Theodore Tso, Johannes Schindelin, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
On 6/25/08, Junio C Hamano <gitster@pobox.com> wrote:
> "Avery Pennarun" <apenwarr@gmail.com> writes:
> >> * You say "git checkout -- file" when you want to "check out the file
> >> from the index";
> >
> > The real question here is the --. Is it strictly needed? It's
> > optional in things like git-diff, which just do their best to guess
> > what you mean if you don't use the --.
>
> No, I wrote -- only for clarity, because you can happen to have a branch
> whose name is the same as the file. Otherwise you can safely omit it,
> just like git-diff and any other commands that follow the -- convention.
Oops, I got mixed up. Only git-reset requires the --. Would it make
sense to bring git-reset into line with everything else, then?
Thanks,
Avery
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re* [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:58 ` Avery Pennarun
@ 2008-06-25 21:24 ` Junio C Hamano
2008-06-25 21:34 ` Junio C Hamano
2008-06-26 1:26 ` Junio C Hamano
0 siblings, 2 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 21:24 UTC (permalink / raw)
To: Avery Pennarun
Cc: Junio C Hamano, Theodore Tso, Johannes Schindelin, Johannes Sixt,
Boaz Harrosh, Steven Walter, git, jeske
"Avery Pennarun" <apenwarr@gmail.com> writes:
> On 6/25/08, Junio C Hamano <gitster@pobox.com> wrote:
>> "Avery Pennarun" <apenwarr@gmail.com> writes:
>> >> * You say "git checkout -- file" when you want to "check out the file
>> >> from the index";
>> >
>> > The real question here is the --. Is it strictly needed? It's
>> > optional in things like git-diff, which just do their best to guess
>> > what you mean if you don't use the --.
>>
>> No, I wrote -- only for clarity, because you can happen to have a branch
>> whose name is the same as the file. Otherwise you can safely omit it,
>> just like git-diff and any other commands that follow the -- convention.
>
> Oops, I got mixed up. Only git-reset requires the --. Would it make
> sense to bring git-reset into line with everything else, then?
Ah, interesting. It appears that the current "reset in C" inherited that
bug from the scripted version. It works most of the time without --
except for one place.
# prove that the work tree is clean...
$ git reset --hard
HEAD is now at 7b7f39e Fix use after free() in builtin-fetch
$ git diff
$ git diff --cached
# what's different since HEAD^?
$ git diff --name-only HEAD^
builtin-fetch.c
# reset the path
$ git reset HEAD^ builtin-fetch.c
builtin-fetch.c: needs update
# prove that HEAD did not move
$ git rev-parse HEAD
7b7f39eae6ab0bbcc68d3c42a5b23595880e528f
# prove that work tree did not change
$ git diff HEAD
# prove that index has old version
$ git diff --cached HEAD^
Reset is about resetting the index and --hard option tells it to propagate
the change down to the work tree as well.
There is no "reset to the index", so "reset -- path" would be a redundant
way to spell "reset HEAD path" or "reset HEAD -- path" which is even more
redundant.
As long as builti-fetch.c is not a valid ref, you should be able to get
out of the above mess by any one of:
$ git reset builtin-fetch.c
$ git reset -- builtin-fetch.c
$ git reset HEAD builtin-fetch.c
but the first one complains, saying builtin-fetch.c is not a valid ref.
This may help.
diff --git a/builtin-reset.c b/builtin-reset.c
index f34acb1..c7d60f5 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -194,9 +194,21 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
reflog_action = args_to_str(argv);
setenv("GIT_REFLOG_ACTION", reflog_action, 0);
- if (i < argc && strcmp(argv[i], "--"))
- rev = argv[i++];
-
+ /*
+ * Possible arguments are:
+ *
+ * git reset <rev> <paths>...
+ * git reset <rev> -- <paths>...
+ * git reset -- <paths>...
+ * git reset <paths>...
+ */
+ if (i < argc && strcmp(argv[i], "--")) {
+ /* could be "git reset <path>" */
+ if (get_sha1(argv[i+1], sha1))
+ ;
+ else
+ rev = argv[i++];
+ }
if (get_sha1(rev, sha1))
die("Failed to resolve '%s' as a valid ref.", rev);
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: Re* [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 21:24 ` Re* " Junio C Hamano
@ 2008-06-25 21:34 ` Junio C Hamano
2008-06-26 1:26 ` Junio C Hamano
1 sibling, 0 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 21:34 UTC (permalink / raw)
To: Avery Pennarun
Cc: Junio C Hamano, Theodore Tso, Johannes Schindelin, Johannes Sixt,
Boaz Harrosh, Steven Walter, git, jeske
Junio C Hamano <gitster@pobox.com> writes:
> "Avery Pennarun" <apenwarr@gmail.com> writes:
>
>> On 6/25/08, Junio C Hamano <gitster@pobox.com> wrote:
>>> "Avery Pennarun" <apenwarr@gmail.com> writes:
>>> >> * You say "git checkout -- file" when you want to "check out the file
>>> >> from the index";
>>> >
>>> > The real question here is the --. Is it strictly needed? It's
>>> > optional in things like git-diff, which just do their best to guess
>>> > what you mean if you don't use the --.
>>>
>>> No, I wrote -- only for clarity, because you can happen to have a branch
>>> whose name is the same as the file. Otherwise you can safely omit it,
>>> just like git-diff and any other commands that follow the -- convention.
>>
>> Oops, I got mixed up. Only git-reset requires the --. Would it make
>> sense to bring git-reset into line with everything else, then?
>
> Ah, interesting. It appears that the current "reset in C" inherited that
> bug from the scripted version. It works most of the time without --
> except for one place.
>
> # prove that the work tree is clean...
> $ git reset --hard
> HEAD is now at 7b7f39e Fix use after free() in builtin-fetch
> $ git diff
> $ git diff --cached
>
> # what's different since HEAD^?
> $ git diff --name-only HEAD^
> builtin-fetch.c
>
> # reset the path
> $ git reset HEAD^ builtin-fetch.c
> builtin-fetch.c: needs update
>
> # prove that HEAD did not move
> $ git rev-parse HEAD
> 7b7f39eae6ab0bbcc68d3c42a5b23595880e528f
> # prove that work tree did not change
> $ git diff HEAD
> # prove that index has old version
> $ git diff --cached HEAD^
>
> Reset is about resetting the index and --hard option tells it to propagate
> the change down to the work tree as well.
>
> There is no "reset to the index", so "reset -- path" would be a redundant
> way to spell "reset HEAD path" or "reset HEAD -- path" which is even more
> redundant.
>
> As long as builti-fetch.c is not a valid ref, you should be able to get
> out of the above mess by any one of:
>
> $ git reset builtin-fetch.c
> $ git reset -- builtin-fetch.c
> $ git reset HEAD builtin-fetch.c
>
> but the first one complains, saying builtin-fetch.c is not a valid ref.
>
> This may help.
>
> diff --git a/builtin-reset.c b/builtin-reset.c
> index f34acb1..c7d60f5 100644
> --- a/builtin-reset.c
> +++ b/builtin-reset.c
> @@ -194,9 +194,21 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
> reflog_action = args_to_str(argv);
> setenv("GIT_REFLOG_ACTION", reflog_action, 0);
>
> - if (i < argc && strcmp(argv[i], "--"))
> - rev = argv[i++];
> -
> + /*
> + * Possible arguments are:
> + *
> + * git reset <rev> <paths>...
> + * git reset <rev> -- <paths>...
> + * git reset -- <paths>...
> + * git reset <paths>...
> + */
> + if (i < argc && strcmp(argv[i], "--")) {
> + /* could be "git reset <path>" */
> + if (get_sha1(argv[i+1], sha1))
typofix: s/i+1/i/;
> + ;
> + else
> + rev = argv[i++];
> + }
> if (get_sha1(rev, sha1))
> die("Failed to resolve '%s' as a valid ref.", rev);
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: Re* [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 21:24 ` Re* " Junio C Hamano
2008-06-25 21:34 ` Junio C Hamano
@ 2008-06-26 1:26 ` Junio C Hamano
1 sibling, 0 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-26 1:26 UTC (permalink / raw)
To: Avery Pennarun
Cc: Junio C Hamano, Theodore Tso, Johannes Schindelin, Johannes Sixt,
Boaz Harrosh, Steven Walter, git, jeske
Junio C Hamano <gitster@pobox.com> writes:
> Reset is about resetting the index and --hard option tells it to propagate
> the change down to the work tree as well.
>
> There is no "reset to the index", so "reset -- path" would be a redundant
> way to spell "reset HEAD path" or "reset HEAD -- path" which is even more
> redundant.
>
> As long as builti-fetch.c is not a valid ref, you should be able to get
> out of the above mess by any one of:
>
> $ git reset builtin-fetch.c
> $ git reset -- builtin-fetch.c
> $ git reset HEAD builtin-fetch.c
>
> but the first one complains, saying builtin-fetch.c is not a valid ref.
>
> This may help.
And this is a cleaned-up patch that is more through.
-- >8 --
Allow "git-reset path" when unambiguous
Resetting a selected set of index entries is done with
"git reset -- paths" syntax, but we did not allow -- to be omitted
even when the command is unambiguous.
This updates the command to follow the general rule:
* When -- appears, revs come before it, and paths come after it;
* When there is no --, earlier ones are revs and the rest are paths, and
we need to guess. When lack of -- marker forces us to guess, we
protect from user errors and typoes by making sure what we treat as
revs do not appear as filenames in the work tree, and what we treat as
paths do appear as filenames in the work tree, and by erroring out if
that is not the case. We tell the user to disambiguate by using -- in
such a case.
which is employed elsewhere in the system.
When this rule is applied to "reset", because we can have only zero or one
rev to the command, the check can be slightly simpler than other programs.
We have to check only the first one or two tokens after the command name
and options, and when they are:
-- A:
no explicit rev given; "A" and whatever follows it are paths.
A --:
explicit rev "A" given and whatever follows the "--" are paths.
A B:
"A" could be rev or path and we need to guess. "B" could
be missing but if exists that (and everything that follows) would
be paths.
So we apply the guess only in the last case and only to "A" (not "B" and
what comes after it).
* As long as "A" is unambiguously a path, index entries for "A", "B" (and
everything that follows) are reset to the HEAD revision.
* If "A" is unambiguously a rev, on the other hand, the index entries for
"B" (and everything that follows) are reset to the "A" revision.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin-reset.c | 39 ++++++++++++++++++++++++++++++++++-----
t/t7102-reset.sh | 47 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+), 5 deletions(-)
diff --git a/builtin-reset.c b/builtin-reset.c
index f34acb1..a032169 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -194,8 +194,40 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
reflog_action = args_to_str(argv);
setenv("GIT_REFLOG_ACTION", reflog_action, 0);
- if (i < argc && strcmp(argv[i], "--"))
- rev = argv[i++];
+ /*
+ * Possible arguments are:
+ *
+ * git reset [-opts] <rev> <paths>...
+ * git reset [-opts] <rev> -- <paths>...
+ * git reset [-opts] -- <paths>...
+ * git reset [-opts] <paths>...
+ *
+ * At this point, argv[i] points immediately after [-opts].
+ */
+
+ if (i < argc) {
+ if (!strcmp(argv[i], "--")) {
+ i++; /* reset to HEAD, possibly with paths */
+ } else if (i + 1 < argc && !strcmp(argv[i+1], "--")) {
+ rev = argv[i];
+ i += 2;
+ }
+ /*
+ * Otherwise, argv[i] could be either <rev> or <paths> and
+ * has to be unambigous.
+ */
+ else if (!get_sha1(argv[i], sha1)) {
+ /*
+ * Ok, argv[i] looks like a rev; it should not
+ * be a filename.
+ */
+ verify_non_filename(prefix, argv[i]);
+ rev = argv[i++];
+ } else {
+ /* Otherwise we treat this as a filename */
+ verify_filename(prefix, argv[i]);
+ }
+ }
if (get_sha1(rev, sha1))
die("Failed to resolve '%s' as a valid ref.", rev);
@@ -205,9 +237,6 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
die("Could not parse object '%s'.", rev);
hashcpy(sha1, commit->object.sha1);
- if (i < argc && !strcmp(argv[i], "--"))
- i++;
-
/* git reset tree [--] paths... can be used to
* load chosen paths from the tree into the index without
* affecting the working tree nor HEAD. */
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index 39ba141..96d1508 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -428,4 +428,51 @@ test_expect_success '--mixed refreshes the index' '
test_cmp expect output
'
+test_expect_success 'disambiguation (1)' '
+
+ git reset --hard &&
+ >secondfile &&
+ git add secondfile &&
+ test_must_fail git reset secondfile &&
+ test -z "$(git diff --cached --name-only)" &&
+ test -f secondfile &&
+ test ! -s secondfile
+
+'
+
+test_expect_success 'disambiguation (2)' '
+
+ git reset --hard &&
+ >secondfile &&
+ git add secondfile &&
+ rm -f secondfile &&
+ test_must_fail git reset secondfile &&
+ test -n "$(git diff --cached --name-only -- secondfile)" &&
+ test ! -f secondfile
+
+'
+
+test_expect_success 'disambiguation (3)' '
+
+ git reset --hard &&
+ >secondfile &&
+ git add secondfile &&
+ rm -f secondfile &&
+ test_must_fail git reset HEAD secondfile &&
+ test -z "$(git diff --cached --name-only)" &&
+ test ! -f secondfile
+
+'
+
+test_expect_success 'disambiguation (4)' '
+
+ git reset --hard &&
+ >secondfile &&
+ git add secondfile &&
+ rm -f secondfile &&
+ test_must_fail git reset -- secondfile &&
+ test -z "$(git diff --cached --name-only)" &&
+ test ! -f secondfile
+'
+
test_done
^ permalink raw reply related [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:11 ` Junio C Hamano
2008-06-25 20:22 ` Avery Pennarun
@ 2008-06-25 20:37 ` Steven Walter
1 sibling, 0 replies; 113+ messages in thread
From: Steven Walter @ 2008-06-25 20:37 UTC (permalink / raw)
To: Junio C Hamano
Cc: Avery Pennarun, Theodore Tso, Johannes Schindelin, Johannes Sixt,
Boaz Harrosh, git, jeske
On Wed, Jun 25, 2008 at 4:11 PM, Junio C Hamano <gitster@pobox.com> wrote:
> * You say "git checkout branch" when you want to "check out that branch";
>
> * You say "git checkout -- file" when you want to "check out the file
> from the index";
>
> * You say "git checkout v1.5 -- file" when you want to "check out the
> file out of that revision".
>
> It's not that hard.
No, it's not "that hard." But are you really claiming that it's
beyond improvement?
--
-Steven Walter <stevenrwalter@gmail.com>
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:04 ` Avery Pennarun
2008-06-25 20:11 ` Junio C Hamano
@ 2008-06-25 20:38 ` Theodore Tso
2008-06-25 20:50 ` Junio C Hamano
2008-06-25 22:44 ` Petr Baudis
1 sibling, 2 replies; 113+ messages in thread
From: Theodore Tso @ 2008-06-25 20:38 UTC (permalink / raw)
To: Avery Pennarun
Cc: Junio C Hamano, Johannes Schindelin, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
On Wed, Jun 25, 2008 at 04:04:47PM -0400, Avery Pennarun wrote:
> How about making "git checkout" default to HEAD if no revision is
> supplied? There's precedent for this in, say, git-diff (and I think a
> few others).
>
> Incidentally, "checkout <filename>" was also the way to do a revert
> operation in CVS. And the way to switch branches, too, iirc. So git
> isn't being too unusual here. That said, the commands were
> deliberately renamed in svn because CVS was considered largely insane.
The one thing I would worry about is the potential ambiguity if you do
something like "git checkout FOOBAR", and FOOBAR was both a branch
name as well as a file name. How should it be interpreted? I'd argue
the real problem was we conflated two distinct operations: "switching
to a new branch", and "reverting a file" to the same name, checkout.
Hence the suggestion to add a new command, "git revert-file", where
there would be no ambiguity.
- Ted
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:38 ` Theodore Tso
@ 2008-06-25 20:50 ` Junio C Hamano
2008-06-25 21:05 ` Theodore Tso
2008-06-25 22:44 ` Petr Baudis
1 sibling, 1 reply; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 20:50 UTC (permalink / raw)
To: Theodore Tso
Cc: Avery Pennarun, Johannes Schindelin, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
Theodore Tso <tytso@mit.edu> writes:
> The one thing I would worry about is the potential ambiguity if you do
> something like "git checkout FOOBAR", and FOOBAR was both a branch
> name as well as a file name. How should it be interpreted? I'd argue
> the real problem was we conflated two distinct operations: "switching
> to a new branch", and "reverting a file" to the same name, checkout.
I just replied to Avery about that. -- is always the way to disambiguate
between refs (that come before --) and paths (that come after --), not
limited to "git checkout" but with other commands such as "git log", "git
diff", etc.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:50 ` Junio C Hamano
@ 2008-06-25 21:05 ` Theodore Tso
2008-06-25 21:35 ` Junio C Hamano
0 siblings, 1 reply; 113+ messages in thread
From: Theodore Tso @ 2008-06-25 21:05 UTC (permalink / raw)
To: Junio C Hamano
Cc: Avery Pennarun, Johannes Schindelin, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
On Wed, Jun 25, 2008 at 01:50:06PM -0700, Junio C Hamano wrote:
> I just replied to Avery about that. -- is always the way to disambiguate
> between refs (that come before --) and paths (that come after --), not
> limited to "git checkout" but with other commands such as "git log", "git
> diff", etc.
Stupid quesiton --- where is this documented? I don't see this
documented either in the man page for git or git-checkout.
Regards,
- Ted
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 21:05 ` Theodore Tso
@ 2008-06-25 21:35 ` Junio C Hamano
2008-06-26 5:16 ` Junio C Hamano
[not found] ` <20080627193325.6117@nanako3.lavabit.com>
0 siblings, 2 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 21:35 UTC (permalink / raw)
To: Theodore Tso
Cc: Avery Pennarun, Johannes Schindelin, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
Theodore Tso <tytso@mit.edu> writes:
> On Wed, Jun 25, 2008 at 01:50:06PM -0700, Junio C Hamano wrote:
>> I just replied to Avery about that. -- is always the way to disambiguate
>> between refs (that come before --) and paths (that come after --), not
>> limited to "git checkout" but with other commands such as "git log", "git
>> diff", etc.
>
> Stupid quesiton --- where is this documented? I don't see this
> documented either in the man page for git or git-checkout.
You are asking a wrong person. My git knowledge mostly comes from
yearlong reading of the mailing list articles, and doing a bit myself also
helps ;-).
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 21:35 ` Junio C Hamano
@ 2008-06-26 5:16 ` Junio C Hamano
[not found] ` <20080627193325.6117@nanako3.lavabit.com>
1 sibling, 0 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-26 5:16 UTC (permalink / raw)
To: Theodore Tso
Cc: Avery Pennarun, Johannes Schindelin, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
Junio C Hamano <gitster@pobox.com> writes:
> Theodore Tso <tytso@mit.edu> writes:
>
>> On Wed, Jun 25, 2008 at 01:50:06PM -0700, Junio C Hamano wrote:
>>> I just replied to Avery about that. -- is always the way to disambiguate
>>> between refs (that come before --) and paths (that come after --), not
>>> limited to "git checkout" but with other commands such as "git log", "git
>>> diff", etc.
>>
>> Stupid quesiton --- where is this documented? I don't see this
>> documented either in the man page for git or git-checkout.
>
> You are asking a wrong person. My git knowledge mostly comes from
> yearlong reading of the mailing list articles, and doing a bit myself also
> helps ;-).
I couldn't find a good central place to place this as this is more or less
used consistently throughout the UI (log, diff, grep, and then I just
fixed reset as well).
Whereever the description should end up to be in, here is what I think we
should talk about.
Documentation/gitcli.txt | 37 +++++++++++++++++++++++++++++++++----
1 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt
index 8fb5d88..2316049 100644
--- a/Documentation/gitcli.txt
+++ b/Documentation/gitcli.txt
@@ -13,8 +13,37 @@ gitcli
DESCRIPTION
-----------
-This manual describes best practice in how to use git CLI. Here are
-the rules that you should follow when you are scripting git:
+This manual describes the convention used throughout git CLI.
+
+Many commands take revisions (most often "commits", but sometimes
+"tree-ish", depending on the context and command) and paths as their
+arguments. Here are the rules:
+
+ * Revisions come first and then paths.
+ E.g. in `git diff v1.0 v2.0 arch/x86 include/asm-x86`,
+ `v1.0` and `v2.0` are revisions and `arch/x86` and `include/asm-x86`
+ are paths.
+
+ * When an argument can be misunderstood as either a revision or a path,
+ they can be disambiguated by placing `\--` between them.
+ E.g. `git diff \-- HEAD` is, "I have a file called HEAD in my work
+ tree. Please show changes between the version I staged in the index
+ and what I have in the work tree for that file". not "show difference
+ between the HEAD commit and the work tree as a whole". You can say
+ `git diff HEAD \--` to ask for the latter.
+
+ * Without disambiguating `\--`, git makes a reasonable guess, but errors
+ out and asking you to disambiguate when ambiguous. E.g. if you have a
+ file called HEAD in your work tree, `git diff HEAD` is ambiguous, and
+ you have to say either `git diff HEAD \--` or `git diff \-- HEAD` to
+ disambiguate.
+
+When writing a script that is expected to handle random user-input, it is
+a good practice to make it explicit which arguments are which by placing
+disambiguating `\--` at appropriate places.
+
+Here are the rules regarding the "flags" that you should follow when you are
+scripting git:
* it's preferred to use the non dashed form of git commands, which means that
you should prefer `"git foo"` to `"git-foo"`.
@@ -34,8 +63,8 @@ the rules that you should follow when you are scripting git:
if you happen to have a file called `HEAD` in the work tree.
-ENHANCED CLI
-------------
+ENHANCED OPTION PARSER
+----------------------
From the git 1.5.4 series and further, many git commands (not all of them at the
time of the writing though) come with an enhanced option parser.
^ permalink raw reply related [flat|nested] 113+ messages in thread[parent not found: <20080627193325.6117@nanako3.lavabit.com>]
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
[not found] ` <20080627193325.6117@nanako3.lavabit.com>
@ 2008-06-27 22:11 ` Junio C Hamano
2008-06-28 0:06 ` しらいしななこ
0 siblings, 1 reply; 113+ messages in thread
From: Junio C Hamano @ 2008-06-27 22:11 UTC (permalink / raw)
To: しらいしななこ
Cc: Theodore Tso, Avery Pennarun, Johannes Schindelin, Johannes Sixt,
Boaz Harrosh, Steven Walter, git, jeske
しらいしななこ <nanako3@lavabit.com> writes:
> Quoting Junio C Hamano <gitster@pobox.com>:
>
>> > Theodore Tso <tytso@mit.edu> writes:
>> > ...
>> >> Stupid quesiton --- where is this documented? I don't see this
>> >> documented either in the man page for git or git-checkout.
>> >
>> > You are asking a wrong person. My git knowledge mostly comes from
>> > yearlong reading of the mailing list articles, and doing a bit myself also
>> > helps ;-).
>>
>> I couldn't find a good central place to place this as this is more or less
>> used consistently throughout the UI (log, diff, grep, and then I just
>> fixed reset as well).
>>
>> Whereever the description should end up to be in, here is what I think we
>> should talk about.
>
> Because it is where the convention that is used in all of the UI is
> described, I think gitcli documentation is an appropriate place.
I am still not convinced it is the best place but I guess it would be
better than not documenting it anywhere.
> Don't you also want to talk about distinction between --cached and
> --index that new people are often confused about? These options are
> defined consistently across commands but people who do not know it bring
> up discussions to rename --cached to some commands to --index to make it
> inconsistent and waste your time every once in a while.
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-27 22:11 ` Junio C Hamano
@ 2008-06-28 0:06 ` しらいしななこ
2008-06-28 22:32 ` しらいしななこ
0 siblings, 1 reply; 113+ messages in thread
From: しらいしななこ @ 2008-06-28 0:06 UTC (permalink / raw)
To: Junio C Hamano
Cc: Theodore Tso, Avery Pennarun, Johannes Schindelin, Johannes Sixt,
Boaz Harrosh, Steven Walter, git, jeske
Quoting Junio C Hamano <gitster@pobox.com>:
>> Because it is where the convention that is used in all of the UI is
>> described, I think gitcli documentation is an appropriate place.
>
> I am still not convinced it is the best place but I guess it would be
> better than not documenting it anywhere.
>
>> Don't you also want to talk about distinction between --cached and
>> --index that new people are often confused about? These options are
>> defined consistently across commands but people who do not know it bring
>> up discussions to rename --cached to some commands to --index to make it
>> inconsistent and waste your time every once in a while.
Do you have any comment on the --index/--cached issue?
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-28 0:06 ` しらいしななこ
@ 2008-06-28 22:32 ` しらいしななこ
2008-06-29 8:56 ` Junio C Hamano
0 siblings, 1 reply; 113+ messages in thread
From: しらいしななこ @ 2008-06-28 22:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
Quoting myself:
>>> Don't you also want to talk about distinction between --cached and
>>> --index that new people are often confused about? These options are
>>> defined consistently across commands but people who do not know it bring
>>> up discussions to rename --cached to some commands to --index to make it
>>> inconsistent and waste your time every once in a while.
>
> Do you have any comment on the --index/--cached issue?
Junio, I haven't heard back from you yet and I take it you mean you are not interested in a vague suggestion but in a concrete patch, so here it is.
-- cut here -- 8< -- cut here --
Subject: [PATCH] gitcli: Document meaning of --cached and --index
We saw this explanation repeated on the git mailing list a
few times. Even though the description of individual options
to particular commands are explained in their manual pages,
the reason behind choosing which is which has been clearly
explained in none of the documentation.
Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
---
Documentation/gitcli.txt | 38 +++++++++++++++++++++++++++++++++++++-
1 files changed, 37 insertions(+), 1 deletions(-)
diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt
index 2316049..281a987 100644
--- a/Documentation/gitcli.txt
+++ b/Documentation/gitcli.txt
@@ -133,9 +133,45 @@ $ git describe --abbrev 10 HEAD # NOT WHAT YOU MEANT
----------------------------
+NOTES ON FREQUENTLY CONFUSED OPTIONS
+------------------------------------
+
+Many commands that can work on files in the working tree
+and/or in the index can take `--cached` and/or `--index`
+options. Sometimes people incorrectly think that, because
+the index was originally called cache, these two are
+synonyms. They are _not_ --- these two options mean very
+different things.
+
+ * The `--cached` option is used to ask a command that
+ usually works on files in the working tree to _only_ work
+ with the index. For example, `git grep`, when used
+ without a commit to specify from which commit to look for
+ strings in, usually works on files in the working tree,
+ but with the `--cached` option, it looks for strings in
+ the index.
+
+ * The `--index` option is used to ask a command that
+ usually works on files in the working tree to _also_
+ affect the index. For example, `git stash apply` usually
+ merges changes recorded in a stash to the working tree,
+ but with the `--index` option, it also merges changes to
+ the index as well.
+
+`git apply` command can be used with `--cached` and
+`--index` (but not at the same time). Usually the command
+only affects the files in the working tree, but with
+`--index`, it patches both the files and their index
+entries, and with `--cached`, it modifies only the index
+entries.
+
+See also http://marc.info/?l=git&m=116563135620359 and
+http://marc.info/?l=git&m=119150393620273 for further
+information.
+
Documentation
-------------
-Documentation by Pierre Habouzit.
+Documentation by Pierre Habouzit and others.
GIT
---
--
1.5.6
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply related [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-28 22:32 ` しらいしななこ
@ 2008-06-29 8:56 ` Junio C Hamano
0 siblings, 0 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-29 8:56 UTC (permalink / raw)
To: しらいしななこ; +Cc: Git Mailing List
しらいしななこ <nanako3@lavabit.com> writes:
> Quoting myself:
>
>>>> Don't you also want to talk about distinction between --cached and
>>>> --index that new people are often confused about? These options are
>>>> defined consistently across commands but people who do not know it bring
>>>> up discussions to rename --cached to some commands to --index to make it
>>>> inconsistent and waste your time every once in a while.
>...
> Junio, I haven't heard back from you yet and I take it you mean you are not interested in a vague suggestion but in a concrete patch, so here it is.
Well, I pretended that I did not notice the original question because I
wanted to avoid addressing this issue ;-<.
While I think --index/--cached are not particularly good pair of words, as
one of the old article you pointed at in your documentation update states,
to describe the distinction, the commands do use them consistently to
differentiate what are operands to them clearly and consistently. In that
sense, your documentation update would probably be a good idea. At least
it makes it easier for new people to learn it just once, and once you know
the distinction and remember which is which, you can reuse the knowledge
to all the commands.
Even though I myself freely admit that these are not particularly a good
pair of words, it is not realistic to expect --index and --cached to ever
be deprecated. But every time this comes up on the list, people end up
wasting time trying to repaint this old bikeshed. That is the primary
reason I did not want to talk about it. It still is possible to introduce
a pair of synonyms that new people might find more descriptive, perhaps:
--index-only = --cached
--index-also = --index
but I personally do not think it would add much value to the system..
> +NOTES ON FREQUENTLY CONFUSED OPTIONS
> +------------------------------------
Hmmm. Is this in anticipation for more "confusing" options described in
this section?
> +Many commands that can work on files in the working tree
> +and/or in the index can take `--cached` and/or `--index`
> +options. Sometimes people incorrectly think that, because
> +the index was originally called cache, these two are
> +synonyms. They are _not_ --- these two options mean very
In e-mails we use _underscore_ but I do not think it works in AsciiDoc.
I'll munge this (you have others below) to "*not*". Also unlike LaTeX,
long dash is two dashes (--), not three (---).
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 20:38 ` Theodore Tso
2008-06-25 20:50 ` Junio C Hamano
@ 2008-06-25 22:44 ` Petr Baudis
2008-06-26 1:59 ` Johannes Schindelin
1 sibling, 1 reply; 113+ messages in thread
From: Petr Baudis @ 2008-06-25 22:44 UTC (permalink / raw)
To: Theodore Tso
Cc: Avery Pennarun, Junio C Hamano, Johannes Schindelin,
Johannes Sixt, Boaz Harrosh, Steven Walter, git, jeske
On Wed, Jun 25, 2008 at 04:38:22PM -0400, Theodore Tso wrote:
> On Wed, Jun 25, 2008 at 04:04:47PM -0400, Avery Pennarun wrote:
> > How about making "git checkout" default to HEAD if no revision is
> > supplied? There's precedent for this in, say, git-diff (and I think a
> > few others).
> >
> > Incidentally, "checkout <filename>" was also the way to do a revert
> > operation in CVS. And the way to switch branches, too, iirc. So git
> > isn't being too unusual here. That said, the commands were
> > deliberately renamed in svn because CVS was considered largely insane.
>
> The one thing I would worry about is the potential ambiguity if you do
> something like "git checkout FOOBAR", and FOOBAR was both a branch
> name as well as a file name. How should it be interpreted? I'd argue
> the real problem was we conflated two distinct operations: "switching
> to a new branch", and "reverting a file" to the same name, checkout.
>
> Hence the suggestion to add a new command, "git revert-file", where
> there would be no ambiguity.
Just to chime in, this reminds me of Cogito - it had cg-switch for
switching branches (like git checkout) and cg-restore for restoring
files in working copy (like git checkout, too; but you would pass -f if
you wanted to overwrite existing copy).
(Though, Cogito didn't quite get it right either since it tried to
overload cg-switch with the git branch functionality of creating new
branches. I still didn't quite come in terms with any UI model of the
branches I know about.)
--
Petr "Pasky" Baudis
The last good thing written in C++ was the Pachelbel Canon. -- J. Olson
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 22:44 ` Petr Baudis
@ 2008-06-26 1:59 ` Johannes Schindelin
0 siblings, 0 replies; 113+ messages in thread
From: Johannes Schindelin @ 2008-06-26 1:59 UTC (permalink / raw)
To: Petr Baudis
Cc: Theodore Tso, Avery Pennarun, Junio C Hamano, Johannes Sixt,
Boaz Harrosh, Steven Walter, git, jeske
Hi,
On Thu, 26 Jun 2008, Petr Baudis wrote:
> On Wed, Jun 25, 2008 at 04:38:22PM -0400, Theodore Tso wrote:
> > On Wed, Jun 25, 2008 at 04:04:47PM -0400, Avery Pennarun wrote:
> > > How about making "git checkout" default to HEAD if no revision is
> > > supplied? There's precedent for this in, say, git-diff (and I think
> > > a few others).
> > >
> > > Incidentally, "checkout <filename>" was also the way to do a revert
> > > operation in CVS. And the way to switch branches, too, iirc. So
> > > git isn't being too unusual here. That said, the commands were
> > > deliberately renamed in svn because CVS was considered largely
> > > insane.
> >
> > The one thing I would worry about is the potential ambiguity if you do
> > something like "git checkout FOOBAR", and FOOBAR was both a branch
> > name as well as a file name. How should it be interpreted? I'd argue
> > the real problem was we conflated two distinct operations: "switching
> > to a new branch", and "reverting a file" to the same name, checkout.
> >
> > Hence the suggestion to add a new command, "git revert-file", where
> > there would be no ambiguity.
>
> Just to chime in, this reminds me of Cogito - it had cg-switch for
> switching branches (like git checkout) and cg-restore for restoring
> files in working copy (like git checkout, too; but you would pass -f if
> you wanted to overwrite existing copy).
Yeah, I was kinda disappointed that this part of Cogito never was picked
up by Git "core".
I really liked the fact that Cogito was a test-bed for UI enhancements,
and miss it a bit. It was nice how it drove the UI enhancements of Git,
and I am a little sad that Cogito was discontinued. (And no, I do not see
any contender picking up the task of driving Git's UI in the right
direction.)
> (Though, Cogito didn't quite get it right either since it tried to
> overload cg-switch with the git branch functionality of creating new
> branches. I still didn't quite come in terms with any UI model of the
> branches I know about.)
To the contrary, I think that "git branch --create <branch>" _should_
switch to the newly created branch. That is what users expect, and Cogito
got that right.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 19:50 ` Theodore Tso
2008-06-25 20:04 ` Avery Pennarun
@ 2008-06-25 20:09 ` Junio C Hamano
1 sibling, 0 replies; 113+ messages in thread
From: Junio C Hamano @ 2008-06-25 20:09 UTC (permalink / raw)
To: Theodore Tso
Cc: Johannes Schindelin, Johannes Sixt, Boaz Harrosh, Steven Walter,
git, jeske
Theodore Tso <tytso@mit.edu> writes:
> On Wed, Jun 25, 2008 at 10:22:08AM -0700, Junio C Hamano wrote:
>> Isn't that this?
>>
>> #!/bin/sh
>> exec git checkout HEAD -- "$@"
>
> Well, I think you really want this to handle filenames with spaces:
Sorry, I do not understand that remark. Does "$@" corrupt embedded spaces
in its parameters?
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 17:22 ` Junio C Hamano
2008-06-25 19:50 ` Theodore Tso
@ 2008-06-26 11:55 ` Björn Steinbrink
2008-06-26 12:07 ` Johannes Schindelin
1 sibling, 1 reply; 113+ messages in thread
From: Björn Steinbrink @ 2008-06-26 11:55 UTC (permalink / raw)
To: Junio C Hamano
Cc: Theodore Tso, Johannes Schindelin, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
On 2008.06.25 10:22:08 -0700, Junio C Hamano wrote:
> Theodore Tso <tytso@mit.edu> writes:
>
> > I used to argue for this, but gave up, because no one seemed to agree
> > with me. So now I just have the following in
> > /home/tytso/bin/git-revert-file and I am very happy:
> >
> > #!/bin/sh
> > #
> > prefix=$(git rev-parse --show-prefix)
> >
> > for i in $*
> > do
> > git show HEAD:$prefix$i > $i
> > done
>
> Isn't that this?
>
> #!/bin/sh
> exec git checkout HEAD -- "$@"
I thought so at first, too, but there's one difference. Ted's version
doesn't affect the index, while yours does. Of course I cannot tell if
Ted actually intended not to touch the index ;-)
Björn
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-26 11:55 ` Björn Steinbrink
@ 2008-06-26 12:07 ` Johannes Schindelin
2008-06-26 12:35 ` Björn Steinbrink
2008-06-26 15:55 ` Avery Pennarun
0 siblings, 2 replies; 113+ messages in thread
From: Johannes Schindelin @ 2008-06-26 12:07 UTC (permalink / raw)
To: Björn Steinbrink
Cc: Junio C Hamano, Theodore Tso, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1093 bytes --]
Hi,
On Thu, 26 Jun 2008, Björn Steinbrink wrote:
> On 2008.06.25 10:22:08 -0700, Junio C Hamano wrote:
> > Theodore Tso <tytso@mit.edu> writes:
> >
> > > I used to argue for this, but gave up, because no one seemed to agree
> > > with me. So now I just have the following in
> > > /home/tytso/bin/git-revert-file and I am very happy:
> > >
> > > #!/bin/sh
> > > #
> > > prefix=$(git rev-parse --show-prefix)
> > >
> > > for i in $*
> > > do
> > > git show HEAD:$prefix$i > $i
> > > done
> >
> > Isn't that this?
> >
> > #!/bin/sh
> > exec git checkout HEAD -- "$@"
>
> I thought so at first, too, but there's one difference. Ted's version
> doesn't affect the index, while yours does. Of course I cannot tell if
> Ted actually intended not to touch the index ;-)
While we are nit-picking: Ted's version does not respect autocrlf, while
Junio's does.
Oh, and Junio's version works with spaces and other funny stuff in file
names, while Ted's does not.
Oh, and error checking is correct in Junio's version.
I am sure there are more differences.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-26 12:07 ` Johannes Schindelin
@ 2008-06-26 12:35 ` Björn Steinbrink
2008-06-26 15:55 ` Avery Pennarun
1 sibling, 0 replies; 113+ messages in thread
From: Björn Steinbrink @ 2008-06-26 12:35 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Junio C Hamano, Theodore Tso, Johannes Sixt, Boaz Harrosh,
Steven Walter, git, jeske
On 2008.06.26 13:07:40 +0100, Johannes Schindelin wrote:
> On Thu, 26 Jun 2008, Björn Steinbrink wrote:
>
> > On 2008.06.25 10:22:08 -0700, Junio C Hamano wrote:
> > > Theodore Tso <tytso@mit.edu> writes:
> > >
> > > > I used to argue for this, but gave up, because no one seemed to agree
> > > > with me. So now I just have the following in
> > > > /home/tytso/bin/git-revert-file and I am very happy:
> > > >
> > > > #!/bin/sh
> > > > #
> > > > prefix=$(git rev-parse --show-prefix)
> > > >
> > > > for i in $*
> > > > do
> > > > git show HEAD:$prefix$i > $i
> > > > done
> > >
> > > Isn't that this?
> > >
> > > #!/bin/sh
> > > exec git checkout HEAD -- "$@"
> >
> > I thought so at first, too, but there's one difference. Ted's version
> > doesn't affect the index, while yours does. Of course I cannot tell if
> > Ted actually intended not to touch the index ;-)
>
> While we are nit-picking: Ted's version does not respect autocrlf, while
> Junio's does.
>
> Oh, and Junio's version works with spaces and other funny stuff in file
> names, while Ted's does not.
>
> Oh, and error checking is correct in Junio's version.
>
> I am sure there are more differences.
I didn't intend to nit-pick, sorry if it looked like that. Not touching
the index might have been a conscious decision, but obviously I must
have missed some email that made it clear that it was intended to also
revert the index entry. Very sorry...
Thanks for the information on autocrlf though, didn't know that show
doesn't care about that.
Björn
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-26 12:07 ` Johannes Schindelin
2008-06-26 12:35 ` Björn Steinbrink
@ 2008-06-26 15:55 ` Avery Pennarun
2008-06-26 17:49 ` Johannes Schindelin
1 sibling, 1 reply; 113+ messages in thread
From: Avery Pennarun @ 2008-06-26 15:55 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Björn Steinbrink, Junio C Hamano, Theodore Tso,
Johannes Sixt, Boaz Harrosh, Steven Walter, git, jeske
On 6/26/08, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> While we are nit-picking: Ted's version does not respect autocrlf, while
> Junio's does.
Is it intentional that git-show doesn't respect autocrlf, or just an oversight?
Avery
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-26 15:55 ` Avery Pennarun
@ 2008-06-26 17:49 ` Johannes Schindelin
0 siblings, 0 replies; 113+ messages in thread
From: Johannes Schindelin @ 2008-06-26 17:49 UTC (permalink / raw)
To: Avery Pennarun
Cc: Björn Steinbrink, Junio C Hamano, Theodore Tso,
Johannes Sixt, Boaz Harrosh, Steven Walter, git, jeske
Hi,
On Thu, 26 Jun 2008, Avery Pennarun wrote:
> On 6/26/08, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > While we are nit-picking: Ted's version does not respect autocrlf,
> > while Junio's does.
>
> Is it intentional that git-show doesn't respect autocrlf, or just an
> oversight?
Funny. I seem to have answered exactly the same question a few days ago.
"git show" is meant to show the contents of an object. It does not
operate on a working directory. It does not even _need_ a working
directory.
So, no, it is _not_ an oversight.
Hth,
Dscho
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 13:51 ` Theodore Tso
2008-06-25 17:22 ` Junio C Hamano
@ 2008-06-26 12:01 ` Matthieu Moy
2008-06-26 12:09 ` Johannes Schindelin
1 sibling, 1 reply; 113+ messages in thread
From: Matthieu Moy @ 2008-06-26 12:01 UTC (permalink / raw)
To: Theodore Tso; +Cc: git
Theodore Tso <tytso@mit.edu> writes:
> for i in $*
Detail: you meant "$@", your version isn't whitespace-robust.
--
Matthieu
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-26 12:01 ` Matthieu Moy
@ 2008-06-26 12:09 ` Johannes Schindelin
2008-06-26 12:23 ` David Kastrup
0 siblings, 1 reply; 113+ messages in thread
From: Johannes Schindelin @ 2008-06-26 12:09 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Theodore Tso, git
Hi,
On Thu, 26 Jun 2008, Matthieu Moy wrote:
> Theodore Tso <tytso@mit.edu> writes:
>
> > for i in $*
>
> Detail: you meant "$@", your version isn't whitespace-robust.
In that case, you'd have to quote the variables in "$prefix$i" and "> $i",
too.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-26 12:09 ` Johannes Schindelin
@ 2008-06-26 12:23 ` David Kastrup
0 siblings, 0 replies; 113+ messages in thread
From: David Kastrup @ 2008-06-26 12:23 UTC (permalink / raw)
To: git
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Hi,
>
> On Thu, 26 Jun 2008, Matthieu Moy wrote:
>
>> Theodore Tso <tytso@mit.edu> writes:
>>
>> > for i in $*
>>
>> Detail: you meant "$@", your version isn't whitespace-robust.
>
> In that case, you'd have to quote the variables in "$prefix$i" and "> $i",
> too.
Yes for the first, no for the second I think. But it would do no harm
in the second case, either. Certainly makes it less shell-dependent.
In fact, just tried it with bash and dash:
dak@lisa:/tmp$ zup="a b c"
dak@lisa:/tmp$ echo x > $zup
bash: $zup: ambiguous redirect
dak@lisa:/tmp$ echo x > "$zup"
dak@lisa:/tmp$ rm "$zup"
dak@lisa:/tmp$ dash
$ zup="a b c"
$ echo x > $zup
$ ls -l "$zup"
-rw-r--r-- 1 dak dak 2 2008-06-26 14:18 a b c
$
Dash gets it right. Bash just talks nonsense. "ambiguous redirect" is
not a useful message at all. There is nothing ambiguous here.
Anyway, bash is prevalent enough to warrant the quoting.
--
David Kastrup
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 9:12 ` Boaz Harrosh
2008-06-25 9:23 ` Junio C Hamano
2008-06-25 10:16 ` Johannes Schindelin
@ 2008-06-25 13:19 ` Ian Hilt
2008-06-26 5:31 ` Andreas Ericsson
3 siblings, 0 replies; 113+ messages in thread
From: Ian Hilt @ 2008-06-25 13:19 UTC (permalink / raw)
To: Boaz Harrosh; +Cc: Junio C Hamano, Steven Walter, git, jeske
On Wed, 25 Jun 2008 at 12:12pm +0300, Boaz Harrosh wrote:
> Junio C Hamano wrote:
> > Learn the lingo, and get over it.
> >
>
> I did lern the lingo and got bitten. I wanted to do one thing
> also got the other one.
Something that I think has not been emphasized enough for whatever
reason is how _easy_ it is to test out git commands. For example, if
you have a really_important_repo that you don't want to screw up, but
you need to do a potentially destructive thing to it, just do,
$ cp -r /path/to/really_important_repo ~/test
$ cd ~/test && git destructive
and you find out whether your mental concept of what "git destructive"
does is correct or not without possibly losing your work.
--
Ian Hilt
Ian.Hilt (at) gmx.com
GnuPG key: 0x4AFC1EE3
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-25 9:12 ` Boaz Harrosh
` (2 preceding siblings ...)
2008-06-25 13:19 ` Ian Hilt
@ 2008-06-26 5:31 ` Andreas Ericsson
2008-06-26 16:15 ` Jon Loeliger
3 siblings, 1 reply; 113+ messages in thread
From: Andreas Ericsson @ 2008-06-26 5:31 UTC (permalink / raw)
To: Boaz Harrosh; +Cc: Junio C Hamano, Steven Walter, git, jeske
Boaz Harrosh wrote:
> Junio C Hamano wrote:
>> Steven Walter <stevenrwalter@gmail.com> writes:
>>
>>> @@ -225,6 +243,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
>>> if (reset_type == HARD && is_bare_repository())
>>> die("hard reset makes no sense in a bare repository");
>>>
>>> + if (reset_type == HARD && !force && index_is_dirty()) {
>>> + die("Uncommitted changes; re-run with -f to trash them");
>>> + }
>>> +
>> Please don't. With your change, does the testsuite even pass?
>>
>> "reset --hard" has *ALWAYS* meant to be destructive --- discarding
>> potential local cruft is the whole point of the operation.
>>
>
> I was under the impression that --hard means working-directory-also
> as opposed to tree-and-index-only. Nothing to do with
> destructive-discarding. If it is then something is missing.
> I need 2 distinct functions. You combine to functions under
> one command.
>
>> Learn the lingo, and get over it.
>>
>
> I did lern the lingo and got bitten. I wanted to do one thing
> also got the other one.
>
> there is:
> git-reset --clean - destructive-discarding any local changes
> git-reset --hard - move tree index and working directory to new head
>
> How can I separate between them, Please
>
There is a "--hard" after one of them. It reads like this:
git reset --hard ;# move current branch to random point in history
# discarding working tree and index state
git reset --mixed ;# move current branch to random point in history
# discard the index but keep the working tree
git reset --soft ;# move current branch to random point in history,
# leaving index and working tree intact
It's under OPTIONS in the man-page. --mixed is default.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-26 5:31 ` Andreas Ericsson
@ 2008-06-26 16:15 ` Jon Loeliger
0 siblings, 0 replies; 113+ messages in thread
From: Jon Loeliger @ 2008-06-26 16:15 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: Boaz Harrosh, Junio C Hamano, Steven Walter, git, jeske
Andreas Ericsson wrote:
> There is a "--hard" after one of them. It reads like this:
>
> git reset --hard ;# move current branch to random point in history
> # discarding working tree and index state
>
> git reset --mixed ;# move current branch to random point in history
> # discard the index but keep the working tree
>
> git reset --soft ;# move current branch to random point in history,
> # leaving index and working tree intact
I always thought that these would be best presented in
a linear ordering so that the effects were clearly
shown in an "increasing" way:
--soft
- touches one thing
--mixed
- touches one thing and a second
- this is the default
--hard
- touches one thing, a second and a third
Want a patch down that line?
jdl
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH] cmd_reset: don't trash uncommitted changes unless told to
2008-06-24 22:21 ` [PATCH] cmd_reset: don't trash uncommitted changes unless told to Steven Walter
2008-06-24 22:31 ` Junio C Hamano
@ 2008-06-25 5:29 ` Johannes Gilger
1 sibling, 0 replies; 113+ messages in thread
From: Johannes Gilger @ 2008-06-25 5:29 UTC (permalink / raw)
To: git
On 24/06/08 18:21, Steven Walter wrote:
> Give "reset --hard" a -f (force) flag, without which it will refuse to
> proceed if there are changes in the index or working tree.
Oh no. I can only agree and repeat myself, as I think this is nonsense.
git is a tool, and like every tool you can hurt yourself with it if you
don't read the manual and follow really simple guidelines. I used git
reset --hard on a test-repo before using it on my real code, and it has
never bit me since. Why do we have --hard then? It would be "An option
which does nothing unless you also specify -f on the command-line".
Just my opinion, but I think quite a few people feel the same
Regards,
Jojo
--
Johannes Gilger <heipei@hackvalue.de>
http://hackvalue.de/heipei/
GPG-Key: 0x42F6DE81
GPG-Fingerprint: BB49 F967 775E BB52 3A81 882C 58EE B178 42F6 DE81
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5zrLdFEDjCV3U>
2008-06-24 20:04 ` David Jeske
@ 2008-06-24 20:04 ` David Jeske
1 sibling, 0 replies; 113+ messages in thread
From: David Jeske @ 2008-06-24 20:04 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Boaz Harrosh, git
> -- David Jeske wrote:
>> - improve the man page description of "reset --hard"
>> - standardize all the potentially destructive operations
>> (after gc) on "-f/--force" to override
>
> The thing is 'force' is not always the most descriptive word
> for the behavior that you propose enabling with --force.
I'm not talking about switching "git reset --hard" to "git reset -f". I'm
talking about requiring a "-f" option to "git reset --hard" when it would
destroy or dangle information.
(a) If you have a clean working directory which is fully checked in and has
another branch tag other than the current branch tag, then "git reset --hard
<commitish>" is non-destructive, and would complete happily.
(b) If you have local modifications to working files it would complain "hey,
your working files are dirty, 'reset --hard' will blow them away, either revert
them or use -f". This is what Boaz asked for, and I doubt it would change along
would alter workflow much for people who are using "git reset --hard" to toss
attempted patches (since they were fully committed anyhow), or even undo a
clone or pull operation. If people use it as a combo "revert and reset", they
would notice.
(c) If the current location is only pointed to by the current branch (which you
are going to move with 'reset --hard') tell the user that those changes will be
dangling and will be eligible for garbage collection if they move the branch.
What to do in this case seems more controversial. I would prefer for this to
error with "either label these changes with 'branch', or use 'reset --hard -f'
to force us to leave these in the reflog unnamed". --- Some here say that
being in the reflog is enough, and the -f is overkill here. If we define
destructive as dropping code-commits, then that's true. If we define
destructive as leaving code-commits unreferenced, then -f is warranted.
Personally, I'd rather git help me avoid dropping the NAMES to tips, because
even with GC-never, I don't really want to find myself crawling through SHA1
hashes and visualization trees to find them later, when git could have reminded
me to name a branch that would conveniently show up in 'git branch'. It's easy
enough to avoid dropping the names, or force git to not care with '-f'. I
personally would like to avoid dealing with reflog or SHA1 hashes 99% of the
time.
> 'gc' is another command that has been mentioned along
> with its '--aggressive' option.
This was an accident. When I made my "mv --aggressive" joke I was NOT intending
to reference "gc --aggressive", that is just a coincidence. I was trying to
make up another 'semi-dangerous sounding name that might or not might be
destructive". It's comical that it's in use for gc. I don't see any
relationship between "gc --aggressive" and destructive behavior.
However, there IS a situation to require a "-f" on a, because again, "-f" would
be required for operations which destroy commits. If we think commits being in
the reflog is good enough to hold onto them, and users are thinking that items
being in the reflog are 'safe', then a GC where reflog entry expiration is
going to cause DAG entries to be removed could print an error like:
error: the following entries are beyond the expiration time,
...<base branchname>/<commit-ish>: 17 commits, 78 lines, 3 authors
...use diff <commit-ish> , to see the changes
...use gc -f, to cause them to be deleted
This wouldn't happen very often, and would make "gc" a safe operation even on
trees with shorter expiration time. In fact, if this were the way it worked, I
might set my GC back from never to "30 days", because this would not only allow
me to safely cleanup junk, but it would also allow me to catch unnamed and
dangling references before they became so old I didn't remember what to name
them.
This would make a "non forced gc" safe from throwing away commits, but still
make it really easy to do so for people who want to. Likewise, we could make
any "auto-gc" that happens not forced by default.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 19:08 ` Jakub Narebski
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5zrLdFEDjCV3U>
@ 2008-06-25 8:57 ` Boaz Harrosh
1 sibling, 0 replies; 113+ messages in thread
From: Boaz Harrosh @ 2008-06-25 8:57 UTC (permalink / raw)
To: Jakub Narebski
Cc: David Jeske, git, Brandon Casey, Theodore Tso, Junio C Hamano
Jakub Narebski wrote:
> Boaz Harrosh <bharrosh@panasas.com> writes:
>
>
>> Sorry
>> git-reset --clean -f/-n for removing local changes
>> git reset --hard for moving HEAD on a clean tree only
>
> Wouldn't "git reset <commit-ish>" be enough then? It modifies where
> current branch points to (as opposed to git-checkout modifying what is
> the current branch), and it modifies index. What it doesn't modify is
> working directory, but it is clean already.
>
Does not work. only --hard will do the job. The working directory is not
touched and if you'll do a git-diff you'll see the diff between old-head
to new-head. But what I want is to start-hack or merge on new-head.
> So the solution is: don't use `--hard'.
>
the closest to git reset --hard that I can think of is:
Lets say I have
$ git-branch -a
* mybranch
remote/master
I can
$ git reset --hard remote/master
Or I can
$ git-checkout -b temp_mybranch remote/master
$ git-branch -M temp_mybranch mybranch
The second will complain if I have local changes.
I have just written 2 scripts. One "git-reset" that
will filter out --hard before calling the original.
Second "git-reset--hard" that will do the above.
Stupid me no more. It will not happen to me again.
Just those poor new users out there, I guess you have to
fall off your bike at least once.
Boaz
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
2008-06-24 17:11 ` Boaz Harrosh
2008-06-24 17:19 ` Boaz Harrosh
@ 2008-06-24 18:18 ` Brandon Casey
1 sibling, 0 replies; 113+ messages in thread
From: Brandon Casey @ 2008-06-24 18:18 UTC (permalink / raw)
To: Boaz Harrosh; +Cc: David Jeske, git
Boaz Harrosh wrote:
> I use git reset --hard in to separate and distinct functions.
> One - to move current branch head around from place to place.
Why?
> Two - Throw away work I've edited
This is valid.
> It has happened to me more then once that I wanted the first
> and also got the second as an un-warned bonus, to the dismay
> of my bosses.
Why are you using 'git reset' to do this? Why not just checkout
the branch? I think you are using 'reset' in ways it is not
intended to be used. Is there something in the documentation that
led you to believe that 'reset --hard' should be used to switch
branches? I do see an example of such a thing in everyday.txt.
It deals with setting 'pu' branch to the tip of the 'next' branch,
but the 'pu' branch has a special meaning in git.
It seems like you are using 'reset' when you should be using 'checkout'.
For example:
$ git branch
* mybranch
master
next
maint
pu
If I have 'mybranch' checked out and I want to make a change on top of
the 'next' branch, I wouldn't do 'git reset --hard next', I would either
'git checkout next' or 'git checkout -b next-feature next' or something
similar.
If I've already merged the changes from mybranch back into upstream, then
it's safe to delete it.
I recommend adopting a branch naming scheme where the branch name describes
the task that is to be accomplished. i.e. 'foo' is a bad branch name.
btw, you are not saving anything by trying to reuse branch names. All
a branch is, is a file with a 40 byte string and a newline. So creating
a branch entails writing 41 bytes to a file. Deleting a branch entails
deleting a single file that is only 41 bytes small.
I suggest trying to adjust your work flow so that 'reset --hard' is not necessary.
-brandon
^ permalink raw reply [flat|nested] 113+ messages in thread
[parent not found: <willow-jeske-01l5PFjPFEDjCfzf-01l5V7wbFEDjCX7V@videotron.ca>]
* Re: why is git destructive by default? (i suggest it not be!)
@ 2008-06-24 4:59 Teemu Likonen
[not found] ` <e80d075a0806232201o3933d154he2b570986604c30a@mail.gmail.com>
0 siblings, 1 reply; 113+ messages in thread
From: Teemu Likonen @ 2008-06-24 4:59 UTC (permalink / raw)
To: David Jeske; +Cc: git
David Jeske wrote (2008-06-24 01:47 -0000):
> As a new user, I'm finding git difficult to trust, because there are
> operations which are destructive by default and capable of
> inadvertently throwing hours or days of work into the bit bucket.
I'm also quite new and I actually feel safe using git, and it's because
of reflog. No matter what I do (except manual reflog expire) I can see
where I was before with command
git log --walk-reflogs
and get everything back. I have needed it a couple of times. So the
safety net is there, one just has to learn to trust it. :-)
Git is much safer than the standard Unix tools like rm, mv and cp.
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: why is git destructive by default? (i suggest it not be!)
@ 2008-06-24 8:35 Björn Steinbrink
0 siblings, 0 replies; 113+ messages in thread
From: Björn Steinbrink @ 2008-06-24 8:35 UTC (permalink / raw)
To: David Jeske; +Cc: Jakub Narebski, Avery Pennarun, Nicolas Pitre, git
On 2008.06.24 08:08:13 -0000, David Jeske wrote:
> To re-ask the same question I asked in my last post, using your ascii
> pictures...
>
>
> Let's assume we're here..
>
> .<---.<---.<---A<---X<---Y <--- master
> \
> \--B<---C <--- customer_A_branch <=== HEAD
>
>
> And this person and everyone else moves their head pointers back to master
> without merging:
>
>
> .<---.<---.<---A<---X<---Y <--- master <=== HEAD
> \
> \--B<---C <--- customer_A_branch
>
>
> Now, five years down the road, our tree looks like:
>
>
> .<---A<---X<---Y<---.<--.<--.(3 years of changes)<---ZZZ<--- master <=== HEAD
> \
> \--B<---C <--- customer_A_branch
>
> And someone does:
>
> git-branch -f customer_A_branch ZZZ
>
> To bring us to:
>
> .<---A<---X<---Y<---.<--.(3 years of changes)<---ZZZ<--- master <=== HEAD
> \ \
> \--B<---C \-- customer_A_branch
>
>
> ..at this point, will a GC keep "B<--C", or garbage collect the commits and
> throw them away?
That would throw away the changes in _that_ repository after the reflog
entry has expired. It would not affect any other repo yet, and if that
developer tries to push that new customer_A_branch, it would be refused,
because it is not a fast-forward. And if the repo he's trying to push to
simply doesn't allow any non-fast-forward pushes, then even push -f
won't help him to destroy anything.
Björn
^ permalink raw reply [flat|nested] 113+ messages in thread
[parent not found: <willow-jeske-01l5oEsvFEDjCjRW>]
* Re: why is git destructive by default? (i suggest it not be!)
@ 2008-06-24 12:21 Olivier Galibert
0 siblings, 0 replies; 113+ messages in thread
From: Olivier Galibert @ 2008-06-24 12:21 UTC (permalink / raw)
To: David Jeske; +Cc: Jakub Narebski, Avery Pennarun, Nicolas Pitre, git
On Tue, Jun 24, 2008 at 11:29:43AM -0000, David Jeske wrote:
> -- Jakub Narebski wrote:
> > If they are using '-f', i.e. force, they should know and be sure what
> > they are doing; it is not much different from 'rm -f *'.
>
> Sure, no problem. I don't want the ability to "rm -f *". I'm raising my hand
> and saying "I don't want the power to do these things, so just turn off all the
> git commands that could be destructive and give me an alternate way to do the
> workflows I need to do". Just like a normal user on a unix machine doesn't run
> around with the power to rm -f /etc all the time, even though they may be able
> to su to root.
But you still have the power to /bin/rm -rf ~, which tends to have
worse results. The root/user separation just tries to protect the
system's integrity from the user. This is similar to git, whch tries
to protect the repository's integrity, which is not the same thing as
the contents.
--force exists because it is sometimes useful. It you block it behind
some config setting, whoever is concerned will just change the config
when he needs the command and never change it back. And windows, fsck
and other things of the kind pretty much ruined the efficiency of
confirmations before dangerous/destructive operations. So there isn't
much left beside engaging your brain before using --force on a
command.
OG.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: why is git destructive by default? (i suggest it not be!)
@ 2008-06-25 18:06 Dmitry Potapov
0 siblings, 0 replies; 113+ messages in thread
From: Dmitry Potapov @ 2008-06-25 18:06 UTC (permalink / raw)
To: David Jeske; +Cc: Brandon Casey, Jakub Narebski, Boaz Harrosh, git
On Tue, Jun 24, 2008 at 10:13:13PM -0000, David Jeske wrote:
>
> Two things I'd like to make it easy for users to never do are:
> - delete data
> - cause refs to be dangling
Why? Let's suppose you work with CVS and you started to edit some
file and then realize than the change that you make is stupid, would
not you want just to discard these change without committing them to
CVS?
Perhaps, you are confused by thinking that git commit and cvs commit
are conceptually same commands. IMHO, far better to analogue to cvs
commit would be git push to a repository with denyNonFastForwards
policy. Git commit allows you to save your changes locally as series
of patches, but until you have not pushed them, they are not in a
permanent storage. You can change these patches, which implies that
old versions may become dangling and will be removed after reflog
expired. The idea of making of making difficult to remove some local
commits is alike the idea of an editor making difficult to remove a
line... You gain nothing from that. What editors do instead is to
provide the Undo action. Similarly, Git allows you to get back to an
old state using the reflog.
Dmitry
^ permalink raw reply [flat|nested] 113+ messages in thread
end of thread, other threads:[~2008-06-29 8:57 UTC | newest]
Thread overview: 113+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <jeske@willow=01l5V7waFEDjChmh>
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5V7wbFEDjCX7V>
2008-06-24 1:47 ` why is git destructive by default? (i suggest it not be!) David Jeske
2008-06-24 1:47 ` David Jeske
2008-06-24 17:11 ` Boaz Harrosh
2008-06-24 17:19 ` Boaz Harrosh
2008-06-24 19:08 ` Jakub Narebski
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5zrLdFEDjCV3U>
2008-06-24 20:04 ` David Jeske
2008-06-24 21:42 ` Brandon Casey
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l63P33FEDjCVQ0>
2008-06-24 22:13 ` David Jeske
2008-06-24 22:13 ` David Jeske
2008-06-24 22:54 ` Theodore Tso
2008-06-24 23:07 ` Junio C Hamano
2008-06-25 2:26 ` Theodore Tso
2008-06-25 8:58 ` Jakub Narebski
2008-06-25 9:14 ` Junio C Hamano
2008-06-26 15:13 ` Brandon Casey
2008-06-24 22:21 ` Steven Walter
2008-06-24 22:21 ` [PATCH] cmd_reset: don't trash uncommitted changes unless told to Steven Walter
2008-06-24 22:31 ` Junio C Hamano
2008-06-25 9:12 ` Boaz Harrosh
2008-06-25 9:23 ` Junio C Hamano
2008-06-25 9:59 ` Boaz Harrosh
2008-06-25 10:16 ` Johannes Schindelin
2008-06-25 10:24 ` Matthias Kestenholz
2008-06-25 10:46 ` Anton Gladkov
2008-06-25 12:33 ` Johannes Schindelin
2008-06-25 14:49 ` [PATCH] cmd_reset: don't trash uncommitted changes unless toldto Craig L. Ching
2008-06-25 15:18 ` Anton Gladkov
2008-06-25 10:41 ` [PATCH] cmd_reset: don't trash uncommitted changes unless told to Johannes Sixt
2008-06-25 12:38 ` Johannes Schindelin
2008-06-25 13:51 ` Theodore Tso
2008-06-25 17:22 ` Junio C Hamano
2008-06-25 19:50 ` Theodore Tso
2008-06-25 20:04 ` Avery Pennarun
2008-06-25 20:11 ` Junio C Hamano
2008-06-25 20:22 ` Avery Pennarun
2008-06-25 20:48 ` Junio C Hamano
2008-06-25 20:58 ` Avery Pennarun
2008-06-25 21:24 ` Re* " Junio C Hamano
2008-06-25 21:34 ` Junio C Hamano
2008-06-26 1:26 ` Junio C Hamano
2008-06-25 20:37 ` Steven Walter
2008-06-25 20:38 ` Theodore Tso
2008-06-25 20:50 ` Junio C Hamano
2008-06-25 21:05 ` Theodore Tso
2008-06-25 21:35 ` Junio C Hamano
2008-06-26 5:16 ` Junio C Hamano
[not found] ` <20080627193325.6117@nanako3.lavabit.com>
2008-06-27 22:11 ` Junio C Hamano
2008-06-28 0:06 ` しらいしななこ
2008-06-28 22:32 ` しらいしななこ
2008-06-29 8:56 ` Junio C Hamano
2008-06-25 22:44 ` Petr Baudis
2008-06-26 1:59 ` Johannes Schindelin
2008-06-25 20:09 ` Junio C Hamano
2008-06-26 11:55 ` Björn Steinbrink
2008-06-26 12:07 ` Johannes Schindelin
2008-06-26 12:35 ` Björn Steinbrink
2008-06-26 15:55 ` Avery Pennarun
2008-06-26 17:49 ` Johannes Schindelin
2008-06-26 12:01 ` Matthieu Moy
2008-06-26 12:09 ` Johannes Schindelin
2008-06-26 12:23 ` David Kastrup
2008-06-25 13:19 ` Ian Hilt
2008-06-26 5:31 ` Andreas Ericsson
2008-06-26 16:15 ` Jon Loeliger
2008-06-25 5:29 ` Johannes Gilger
2008-06-24 20:04 ` why is git destructive by default? (i suggest it not be!) David Jeske
2008-06-25 8:57 ` Boaz Harrosh
2008-06-24 18:18 ` Brandon Casey
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5V7wbFEDjCX7V@videotron.ca>
[not found] ` <willow-jeske-01l5cKsCFEDjC=91MX@videotron.ca>
2008-06-24 2:17 ` Nicolas Pitre
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5ciVtFEDjCaD9>
2008-06-24 3:18 ` David Jeske
2008-06-24 3:18 ` David Jeske
2008-06-24 8:14 ` Lea Wiemann
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5ciVtFEDjCaD9@videotron.ca>
[not found] ` <willow-jeske-01l5e9cgFEDjCh3F@videotron.ca>
2008-06-24 4:03 ` Nicolas Pitre
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5fAcTFEDjCWA4>
2008-06-24 4:40 ` David Jeske
2008-06-24 4:40 ` David Jeske
2008-06-24 5:24 ` Jan Krüger
[not found] ` <1978205964779154253@unknownmsgid>
2008-06-24 5:20 ` Avery Pennarun
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5gtQ7FEDjCWCC>
2008-06-24 6:35 ` David Jeske
2008-06-24 6:35 ` David Jeske
2008-06-24 7:24 ` Jeff King
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5jmMuFEDjChvB>
2008-06-24 7:31 ` David Jeske
2008-06-24 8:16 ` Jeff King
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5kv6TFEDjCj8S>
2008-06-24 8:30 ` David Jeske
2008-06-24 9:39 ` Jakub Narebski
2008-06-24 8:30 ` David Jeske
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5kv6TFEDjCj8S@brm-avmta-1.central.sun.com>
[not found] ` <willow-jeske-01l5lTEoFEDjCVta@brm-avmta-1.central.sun.com>
2008-06-24 10:01 ` Fedor Sergeev
2008-06-24 10:24 ` David Jeske
2008-06-24 13:13 ` Theodore Tso
2008-06-24 7:31 ` David Jeske
2008-06-24 7:54 ` Jakub Narebski
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5kQf4FEDjCXUa>
2008-06-24 8:08 ` David Jeske
2008-06-24 8:08 ` David Jeske
2008-06-24 11:22 ` Jakub Narebski
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5p7eVFEDjCZRD>
2008-06-24 11:29 ` David Jeske
2008-06-24 12:19 ` Rogan Dawes
2008-06-24 12:35 ` Johannes Gilger
2008-06-24 12:46 ` Rogan Dawes
2008-06-24 11:29 ` David Jeske
2008-06-24 12:21 ` Jakub Narebski
2008-06-24 12:13 ` Jakub Narebski
2008-06-24 4:59 Teemu Likonen
[not found] ` <e80d075a0806232201o3933d154he2b570986604c30a@mail.gmail.com>
2008-06-24 5:43 ` Teemu Likonen
-- strict thread matches above, loose matches on Subject: below --
2008-06-24 8:35 Björn Steinbrink
[not found] <willow-jeske-01l5oEsvFEDjCjRW>
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5oEswFEDjCZBN>
2008-06-24 10:42 ` David Jeske
2008-06-24 15:29 ` Brandon Casey
[not found] ` <willow-jeske-01l5PFjPFEDjCfzf-01l5uqS9FEDjCcuF>
2008-06-24 16:41 ` David Jeske
2008-06-24 16:41 ` David Jeske
2008-06-24 18:55 ` Brandon Casey
2008-06-25 12:20 ` Matthieu Moy
2008-06-25 17:56 ` Jing Xue
2008-06-24 10:42 ` David Jeske
2008-06-24 12:21 Olivier Galibert
2008-06-25 18:06 Dmitry Potapov
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).