From: Scott Chacon <hidden> Date: 2016-06-15 22:46:56
Hey all,
I have been playing with the EasyGit project lately and I have been
really impressed. I looked back to the last announcement here and the
conversation didn't really go anywhere, sadly. I thought it might be
nice to adopt or at least consider a number of the design decisions
they made in modifying the defaults and commands available. Perhaps
as a 1.7 goal or something? I like it because it addresses a lot of
the issues that I hear from beginning users:
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does, moves
current 'revert' to 'cherry-pick --revert' (which someone mentioned
was a good idea at the last GitTogether), and adds 'unstage' for
'reset HEAD file'. also adds a '-s' option to 'branch' to switch to
the branch after you create it, which many people expect rather than
'checkout -b'.
* adds 'git resolved' for 'git add', which I hear all the time as
being confusing
* adds 'git publish' for creating a bare repo from your current repo
and scp/rsync-ing it to a server (which is nice if you're not using
GitHub/repo.or.cz where remote repo seeding is easier)
* adds 'git info' which shows a bunch of basic information about the
repo, which is actually pretty cool
* more verbose and easily scannable default help output - groups the
commands into categories, etc.
Some other things that might be nice:
* 'git backout' for 'git reset HEAD^'
* 'git push origin --delete <branch>' for 'git push origin :branch'
These things may seem pretty simple and even sort of stupid if you're
used to Git as we are - most of them you can just setup an alias
pretty easily, but you would be amazed at how many people go nuts
because of this stuff. If these simple things were in as defaults,
sooo many of the remaining 'git is hard and obtuse' arguments would
become obsolete. 'checkout', 'add' and 'reset' seem to be where
people have the most difficulty, due to their overloading.
Does this resonate with anyone else? Does 1.7 seem like a good goal
for amending some of these things? Completely redefining 'revert'
seems like the only backward incompatible change - everything else is
just wrappers and whatnot, I think.
Thanks,
Scott
From: Nicolas Pitre <hidden> Date: 2016-06-15 22:46:56
On Tue, 9 Jun 2009, Scott Chacon wrote:
Hey all,
I have been playing with the EasyGit project lately and I have been
really impressed. I looked back to the last announcement here and the
conversation didn't really go anywhere, sadly. I thought it might be
nice to adopt or at least consider a number of the design decisions
they made in modifying the defaults and commands available. Perhaps
as a 1.7 goal or something? I like it because it addresses a lot of
the issues that I hear from beginning users:
[...]
Does this resonate with anyone else? Does 1.7 seem like a good goal
for amending some of these things? Completely redefining 'revert'
seems like the only backward incompatible change - everything else is
just wrappers and whatnot, I think.
Completely agreed.
This is indeed refreshing to see some of the git UI warts being
addressed by people who simply aren't too used to them like I am.
And like you said, most of those changes don't create any
incompatibilities and therefore could be fed back _piecemeal_ into the
main git repository today without even requiring a major version bump.
Nicolas
On Tue, Jun 9, 2009 at 2:59 PM, Scott Chacon[off-list ref] wrote:
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does, moves
current 'revert' to 'cherry-pick --revert' (which someone mentioned
was a good idea at the last GitTogether), and adds 'unstage' for
'reset HEAD file'. also adds a '-s' option to 'branch' to switch to
the branch after you create it, which many people expect rather than
'checkout -b'.
This would definitely make it easier to explain things to svn users.
To be honest, I'm not convinced svn's use of the word "revert" is
really right, though. Git's isn't *really* right either, since it
actually makes a new commit, it doesn't remove the old one like it
sounds like it does. Maybe 'reverse' would be a better name for what
git does, and we should just introduce another word for what svn does.
(With CVS, you just deleted the file and then did a checkout/update
on it again, which made sense to me. That works in git too.)
Crazy idea: we could actually make 'git revert' do both: given a
commit, it applies the reverse as it does now. Given filenames, it
simply brings them back to HEAD. But maybe that's too crazy.
* adds 'git resolved' for 'git add', which I hear all the time as
being confusing
This one doesn't really do it for me. svn's need to "resolve" a file
after removing its conflicts always annoyed me. Look, you can see
I've screwed around with the file. The file contains no more
conflicts. It's resolved, already!
Maybe it's heresy, but I really liked CVS's way of dealing with this:
if the file still has conflict markers in it, it's not resolved. If
it doesn't, then it's resolved. Very hard to mess up. And I've
definitely messed up (and known other people to mess up) with both
svn's method and git's method, both of which allow you to commit files
with conflict markers without getting warned.
* adds 'git publish' for creating a bare repo from your current repo
and scp/rsync-ing it to a server (which is nice if you're not using
GitHub/repo.or.cz where remote repo seeding is easier)
Very cool, and this has been seriously hard to explain to people. I'm
not even sure there *is* a good way to do this without running a
series of several commands.
* adds 'git info' which shows a bunch of basic information about the
repo, which is actually pretty cool
Less important to me, but sounds fine just due to svn compatibility.
This would help a lot of people too, I think. Although some might
argue that "helping" them to delete branches is maybe not a great
idea.
Have fun,
Avery
From: Björn Steinbrink <hidden> Date: 2016-06-15 22:46:56
On 2009.06.09 11:59:08 -0700, Scott Chacon wrote:
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does
Looking through the "eg revert" docs [1], I can't seem to find how you can
do "checkout -- path" with it at all. "eg revert foo" seems to be "git
checkout HEAD -- foo". The "eg revert" looks really confusing to me.
"eg revert --unstaged --in HEAD~8". Hu? Revert unstaged changes in
HEAD~8? Am I missing something?
Björn
[1] http://www.gnome.org/~newren/eg/documentation/revert.html
From: Björn Steinbrink <hidden> Date: 2016-06-15 22:46:56
On 2009.06.09 15:52:46 -0400, Avery Pennarun wrote:
On Tue, Jun 9, 2009 at 2:59 PM, Scott Chacon[off-list ref] wrote:
quoted
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does, moves
current 'revert' to 'cherry-pick --revert' (which someone mentioned
was a good idea at the last GitTogether), and adds 'unstage' for
'reset HEAD file'. also adds a '-s' option to 'branch' to switch to
the branch after you create it, which many people expect rather than
'checkout -b'.
This would definitely make it easier to explain things to svn users.
To be honest, I'm not convinced svn's use of the word "revert" is
really right, though. Git's isn't *really* right either, since it
actually makes a new commit, it doesn't remove the old one like it
sounds like it does. Maybe 'reverse' would be a better name for what
git does, and we should just introduce another word for what svn does.
(With CVS, you just deleted the file and then did a checkout/update
on it again, which made sense to me. That works in git too.)
Crazy idea: we could actually make 'git revert' do both: given a
commit, it applies the reverse as it does now. Given filenames, it
simply brings them back to HEAD. But maybe that's too crazy.
Doesn't seem that crazy to me. But maybe a bit problematic if you want
to support both, "git checkout -- ." and "git checkout HEAD -- .". And
adding DWIMmery there seems dangerous, as in:
git revert == git checkout -- .
git revert HEAD ==
no uncommitted changes = revert commit HEAD
uncommitted changes = revert to HEAD
Björn
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does
Looking through the "eg revert" docs [1], I can't seem to find how you can
do "checkout -- path" with it at all. "eg revert foo" seems to be "git
checkout HEAD -- foo".
If you want to revert only the unstaged changes to path:
"checkout -- path" OR "revert --unstaged path"
If you want to revert both staged and unstaged changes to foo:
"checkout HEAD -- foo" OR "revert foo"
The "eg revert" looks really confusing to me.
"eg revert --unstaged --in HEAD~8". Hu? Revert unstaged changes in
HEAD~8? Am I missing something?
Hmm. Bad ordering, I guess -- it's revert changes in HEAD~8 to the
working copy only (by default, revert tries to apply changes to both
the working copy and the index). Yeah, it doesn't read very well.
I'm not sure I like having "--in" as part of revert, partially because
of this confusion (and partially because I don't think it's
implementation is correct anyway). However, I do occasionally really
like being able to revert the change _to a single file_ made in some
previous commit, so I haven't removed it from eg (yet?). *shrug*
Elijah
On 2009.06.09 15:52:46 -0400, Avery Pennarun wrote:
quoted
To be honest, I'm not convinced svn's use of the word "revert" is
really right, though. Git's isn't *really* right either, since it
actually makes a new commit, it doesn't remove the old one like it
sounds like it does. Maybe 'reverse' would be a better name for what
git does, and we should just introduce another word for what svn does.
(With CVS, you just deleted the file and then did a checkout/update
on it again, which made sense to me. That works in git too.)
Crazy idea: we could actually make 'git revert' do both: given a
commit, it applies the reverse as it does now. Given filenames, it
simply brings them back to HEAD. But maybe that's too crazy.
Doesn't seem that crazy to me. But maybe a bit problematic if you want
to support both, "git checkout -- ." and "git checkout HEAD -- .". And
adding DWIMmery there seems dangerous, as in:
git revert == git checkout -- .
git revert HEAD ==
no uncommitted changes = revert commit HEAD
uncommitted changes = revert to HEAD
Well, that's what I meant by "crazy" :)
Since so many of the other suggestions in eg are so simple and
non-conflicting, perhaps it's best to drop this branch of discussion
until the non-controversial bits are adopted. It would be bad to lose
other great improvements just because this one command is
problematic...
Have fun,
Avery
Crazy idea: we could actually make 'git revert' do both: given a
commit, it applies the reverse as it does now. Given filenames, it
simply brings them back to HEAD. But maybe that's too crazy.
Probably too crazy (too much potential for confusion), but an
interesting thing about the way eg revert was written is that any
valid git revert command passed to eg revert is invalid syntax, so I
can print the simple error message:
If you are used to git revert, try 'eg cherry-pick -R <ARGS>'...
That prevents accidental misuse and misunderstandings, such as these:
Doesn't seem that crazy to me. But maybe a bit problematic if you want
to support both, "git checkout -- ." and "git checkout HEAD -- .". And
adding DWIMmery there seems dangerous, as in:
git revert == git checkout -- .
git revert HEAD ==
no uncommitted changes = revert commit HEAD
uncommitted changes = revert to HEAD
I was thinking that if people had too much heartburn over changing the
meaning of revert from "revert-commit" to "revert-edits", then we
could always submit the eg revert functionality as git-revert-edits.
From: Björn Steinbrink <hidden> Date: 2016-06-15 22:46:56
On 2009.06.09 14:40:33 -0600, Elijah Newren wrote:
Hi,
2009/6/9 Björn Steinbrink [off-list ref]:
quoted
On 2009.06.09 11:59:08 -0700, Scott Chacon wrote:
quoted
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does
Looking through the "eg revert" docs [1], I can't seem to find how you can
do "checkout -- path" with it at all. "eg revert foo" seems to be "git
checkout HEAD -- foo".
If you want to revert only the unstaged changes to path:
"checkout -- path" OR "revert --unstaged path"
If you want to revert both staged and unstaged changes to foo:
"checkout HEAD -- foo" OR "revert foo"
OK, so --unstaged doesn't just select the destination, but also the
source, unless you explicitly override it, right?
eg revert [--since HEAD] path
==> source: HEAD, destination: working tree, index
eg revert --unstaged path
==> source: index, destination: working tree
eg revert --unstaged --since HEAD path
==> source: HEAD, destination: working tree
quoted
The "eg revert" looks really confusing to me.
"eg revert --unstaged --in HEAD~8". Hu? Revert unstaged changes in
HEAD~8? Am I missing something?
Hmm. Bad ordering, I guess -- it's revert changes in HEAD~8 to the
working copy only (by default, revert tries to apply changes to both
the working copy and the index). Yeah, it doesn't read very well.
I'm not sure I like having "--in" as part of revert, partially because
of this confusion (and partially because I don't think it's
implementation is correct anyway). However, I do occasionally really
like being able to revert the change _to a single file_ made in some
previous commit, so I haven't removed it from eg (yet?). *shrug*
I'm not sure that "--in" is the worst thing here. To me, --unstaged is
worse, because I apply the attribute "unstaged" to the changes to be
reverted. And that makes no sense when I supply a commit, a commit
cannot have unstaged changes. I guess that if --unstaged wasn't used to
select the destination, I might have come up with "eg revert --unstaged"
myself, just from seeing the options. But seeing that --unstaged can be
used with a commit confused me.
Björn
From: Björn Steinbrink <hidden> Date: 2016-06-15 22:46:56
On 2009.06.09 11:59:08 -0700, Scott Chacon wrote:
* adds 'git resolved' for 'git add', which I hear all the time as
being confusing
Is "resolve" a plain alias, like "stage", or smart in deciding which
files it accepts? My gut feeling is that a plain alias might cause
trouble again when users get lazy and start to do "git resolve ." and
wonder why that adds new files.
Iff such a "resolve" command is added, it should IMHO only serve the
purpose of changing the status of index entries marked as "unstaged",
and do nothing else that "add" can do. When someone asks why "git add"
is used for telling git that a conflict was resolved, I can say that
"git add" means "add this to the things to be committed" and that that
implies that conflicts have been resolved (I like to describe "git add"
as "tell git that 'this is good to commit'"). So I can give some logical
explanation. But if someone would ask me why "git resolve" can add new
files, which never had a merge conflict, to the index, I'd be pretty
stumped.
Björn
* adds 'git resolved' for 'git add', which I hear all the time as
being confusing
Is "resolve" a plain alias, like "stage", or smart in deciding which
files it accepts? My gut feeling is that a plain alias might cause
trouble again when users get lazy and start to do "git resolve ." and
wonder why that adds new files.
In eg it's currently a plain alias, but I like your arguments for
making it only handle unmerged entries.
Iff such a "resolve" command is added, it should IMHO only serve the
purpose of changing the status of index entries marked as "unstaged",
and do nothing else that "add" can do. When someone asks why "git add"
is used for telling git that a conflict was resolved, I can say that
"git add" means "add this to the things to be committed" and that that
implies that conflicts have been resolved (I like to describe "git add"
as "tell git that 'this is good to commit'"). So I can give some logical
explanation. But if someone would ask me why "git resolve" can add new
files, which never had a merge conflict, to the index, I'd be pretty
stumped.
Hi,
On Tue, Jun 9, 2009 at 12:59 PM, Scott Chacon[off-list ref] wrote:
Hey all,
I have been playing with the EasyGit project lately and I have been
really impressed.
Thanks for bringing this up. I should have done better at proposing
some of these changes upstream...
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does, moves
current 'revert' to 'cherry-pick --revert' (which someone mentioned
was a good idea at the last GitTogether), and adds 'unstage' for
As a side note, the mapping from eg revert to git commands is not so
simple; you'll miss a lot of cases if you were to make a simple alias.
:-)
<snip a highlight of some changes in eg>
I'll note that you can run 'eg changes --details' to get a (hopefully
up-to-date and) complete list...
Some other things that might be nice:
* 'git backout' for 'git reset HEAD^'
May cause confusion for mercurial users (hg backout == current git
revert). I don't have a better proposal, though. 'uncommit'?
Also, a consistency proposal that I have not yet gotten to
implementing in eg; It'd be nice to add more consistency with these
commands:
- continue incomplete am: git am --resolved
- continue incomplete rebase: git rebase --continue
- continue incomplete merge: git commit
so that it looks like this (while still allowing the old ways for
backward compatibility):
=> continue incomplete am: git am --continue
=> continue incomplete rebase: git rebase --continue
=> continue incomplete merge: git merge --continue (or is this
going overboard?)
And to change this:
- abort incomplete am: git am --abort
- abort incomplete bisect: git bisect reset
- abort incomplete merge: git reset --hard HEAD
- abort incomplete rebase: git rebase --abort
so that it looks like this (again still allowing old ways):
=> abort incomplete am: git am --abort
=> abort incomplete bisect: git bisect --abort
=> abort incomplete merge: git merge --abort
=> abort incomplete rebase: git rebase --abort
These things may seem pretty simple and even sort of stupid if you're
used to Git as we are - most of them you can just setup an alias
pretty easily, but you would be amazed at how many people go nuts
because of this stuff. If these simple things were in as defaults,
sooo many of the remaining 'git is hard and obtuse' arguments would
become obsolete. 'checkout', 'add' and 'reset' seem to be where
people have the most difficulty, due to their overloading.
Does this resonate with anyone else? Does 1.7 seem like a good goal
for amending some of these things? Completely redefining 'revert'
seems like the only backward incompatible change - everything else is
just wrappers and whatnot, I think.
Mostly just wrappers, yes. There are two other big incompatible
changes, both to push: (1) 'eg push' is basically hardcoded to do what
push.default=tracking now does (although now that push.default exists,
I'm considering dropping this change in eg), and (2) eg push will try
to check whether the remote repository is bare and deny the push
unless one of the arguments is a refspec that has a ':' character in
it (i.e. a push-side check, rather than git's recent receive-side
check; having both probably doesn't make sense, so it's another thing
I'm reconsidering).
Also, I wondered whether others would consider the different defaults
for commit & diff to be a big backward incompatible change, though the
fact that you didn't seem to notice it and lots of others don't either
suggest it's not that big (for experienced users). There are also
more minor changes to the defaults of bundle, log, and status, but
those are innocuous enough that they hardly qualify as backward
incompatible.
Thanks,
Elijah
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does
No.
NAK on this one.
The fact that some idiotic SVN usage exists is not an excuse to break
long-standing git users. "revert" comes from bk, and quite frankly, I
object _very_ strongly to taking naming from something that is very
obviously the inferior system (SVN) over something very obviously superior
(BK and git).
Feel free to add other "helper" aliases that are actually _new_ and have
no pre-existing git meaning, but not things like this. Not breaking
existing git usage just because somebody is too stupid and/or lazy to try
to learn a new word.
Linus
On Tue, Jun 9, 2009 at 4:14 PM, Linus
Torvalds[off-list ref] wrote:
On Tue, 9 Jun 2009, Scott Chacon wrote:
quoted
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does
No.
<snip>
Feel free to add other "helper" aliases that are actually _new_ and have
no pre-existing git meaning, but not things like this. Not breaking
existing git usage just because somebody is too stupid and/or lazy to try
to learn a new word.
Do you object to using 'revert' in the name of the new command or just
to having the new command take over the exact name 'revert'? I'd like
to propose making the reverting of edits functionality available under
the command name 'revert-edits', while leaving the existing reverting
of commits functionality under 'revert', but I'm not sure if that
would run afoul of your objections as well.
Elijah
Do you object to using 'revert' in the name of the new command or just
to having the new command take over the exact name 'revert'?
I object to changing existing meaning.
I'd like to propose making the reverting of edits functionality
available under the command name 'revert-edits'
That's fine.
I also don't mind per se having the "git checkout" kind of semantics,
where different kinds of arguments result in different kinds of behavior.
I'm not convinced it's a wonderful design, but I would not object to
- old behavior: revert the commit by creating an "anti-commit":
git revert <cmit-name>
- new extension: revert the state of the working tree to the HEAD:
git revert [--] pathspec
which would kind of match the semantics of "git checkout" does.
So it's not that I object to "git revert" as a name. I just object to
changing existing (and sane) semantics just for some silly person who
thinks that git is just "SVN done right".
Git is _soo_ much more than just that. People need to live with the fact
that it's not just a SVN clone.
Linus
From: Mark Lodato <hidden> Date: 2016-06-15 22:46:56
I too would like to see some of the improved UI aspects of EasyGit
merged into git.
On Tue, Jun 9, 2009 at 6:40 PM, Linus
Torvalds[off-list ref] wrote:
So it's not that I object to "git revert" as a name. I just object to
changing existing (and sane) semantics just for some silly person who
thinks that git is just "SVN done right".
Git is _soo_ much more than just that. People need to live with the fact
that it's not just a SVN clone.
I do not think "revert" to mean "checkout --" is just an SVN idiom. I
have heard similar suggestions by people first learning git who have
never used SVN or CVS before. To me, "revert" is a very natural name
for a command to undo changes in the working directory. "Checkout,"
on the other hand, usually means to switch branches, which is
logically distinct from undoing changes in the working tree. In fact,
if one tries to use "checkout" to switch a branch while there are
local changes, git will refuse!
At the same time, "revert" also is a fine name for making an inverse
commit, as revert currently does. So perhaps overloading revert as
you suggest is a good idea. It is wise, as you suggest, to keep
backwards compatibility for existing users.
Mark
From: Sam Vilain <hidden> Date: 2016-06-15 22:46:56
Linus Torvalds wrote:
On Tue, 9 Jun 2009, Scott Chacon wrote:
quoted
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does
No.
NAK on this one.
The fact that some idiotic SVN usage exists is not an excuse to break
long-standing git users. "revert" comes from bk, and quite frankly, I
object _very_ strongly to taking naming from something that is very
obviously the inferior system (SVN) over something very obviously superior
(BK and git).
We talked about this much at GitTogether '08. It's true that for
'reverting' a change in the past, that is the right thing to do. However
I don't think there is a first principles case that this is always what
people mean by 'revert'. And it is not just SVN - Mercurial, Monotone,
Bazaar, Darcs all use 'revert' in this way. By comparison with those
systems, the number of users coming from BK is quite low.
We talked about making a 'git revert-file' and 'git revert-commit', with
'git revert' printing a message encouraging the user to specify which
one they wanted (or potentially pointing them to the correct
incantations of 'git checkout' or 'git cherry-pick').
I think as long as there is a deprecation cycle, and that users can
select the old behaviour (either via an alias or a config option), then
we shouldn't upset many long-time users of revert. Do you agree?
Sam.
We talked about making a 'git revert-file' and 'git revert-commit', with
'git revert' printing a message encouraging the user to specify which
one they wanted (or potentially pointing them to the correct
incantations of 'git checkout' or 'git cherry-pick').
I think as long as there is a deprecation cycle, and that users can
select the old behaviour (either via an alias or a config option), then
we shouldn't upset many long-time users of revert. Do you agree?
No. I disagree. What the hell is the point in making an _inferior_ name
for what we already have?
I violently disagree with making git worse just because somebody cannot
bother to learn it. And it really is about "bother" - it's clearly not
about anything else.
I also don't see why you'd also then advocate a clearly inferior model
with two different commands, when you _could_ just do the "commitname" vs
"pathspec" model.
Linus
On Tue, Jun 09, 2009 at 03:40:35PM -0700, Linus Torvalds wrote:
I also don't mind per se having the "git checkout" kind of semantics,
where different kinds of arguments result in different kinds of behavior.
I'm not convinced it's a wonderful design, but I would not object to
- old behavior: revert the commit by creating an "anti-commit":
git revert <cmit-name>
- new extension: revert the state of the working tree to the HEAD:
git revert [--] pathspec
which would kind of match the semantics of "git checkout" does.
My personal opinion is this kind of overloading is actually more
confusing than simply adding a new name, such as "git revert-file".
Of course, you can do that already using a git alias.... So IMHO the
best way of handling this issue is to have git tutorials use this as a
teachable moment, so people can create their own git alias for "git
checkout HEAD --".
- Ted
My personal opinion is this kind of overloading is actually more
confusing than simply adding a new name, such as "git revert-file".
I'd agree, except I think it actually worked pretty well in "git
checkout".
The alternative was to add yet another command for that, or to teach
people about the internal commands we did have. Adding the capability for
checkout to check out individual files - in addition to commits and
branches - I think worked pretty well.
And "git checkout" in many ways is an even more complicated case, much
more so than the suggested "git revert".
Now, I also happen to think that "git checkout [cmit] -- pathspec" is a
much more _logical_ name for what the SVN people apparently call "revert",
but hey, whatever. If SVN people feel happier about writing "git revert
<pathspec>", then why not?
But I certainly won't argue very sternuously for adding that whole new
"git revert [cmit] [--] <pathspec>" syntax. I can certainly live without
it. I don't think it would be a disaster, though.
Linus
On Tue, Jun 9, 2009 at 9:32 PM, Theodore Tso[off-list ref] wrote:
My personal opinion is this kind of overloading is actually more
confusing than simply adding a new name, such as "git revert-file".
Of course, you can do that already using a git alias.... So IMHO the
best way of handling this issue is to have git tutorials use this as a
teachable moment, so people can create their own git alias for "git
checkout HEAD --".
So I have a few problems with such an alias:
* It fails to work during an initial commit ("git revert-files
new-file" -> "fatal: invalid reference: HEAD")
* When not working on the initial commit, it will silently do nothing
when given a newly added file rather than undoing the add
* As a side effect of the above, trying to undo all changes via "git
revert-files ." does not actually work; any newly added files will
still remain staged.
* It makes no sense during an incomplete merge (why is HEAD more
special than other refs in $git_dir/MERGE_HEAD? Shouldn't the user
need to specify which ref to revert relative to in such a case?)
* It can't be used to revert a file back to a revision prior to HEAD
(and 'git checkout OLDER_COMMIT -- FILE' in such a case isn't always
the right match either as it can leave the file in the working copy
when it should be removed).
* It provides no option to make the changes to just the index or just
the working copy; it always affects both (which is the right default,
but sometimes I like making changes to just one of those two places).
"git checkout <commit> -- <paths>..." really is a different command
than the "revert" of svn, bzr, darcs, or mercurial. There's clearly a
lot of overlap, but they're not the same. I fear that claiming they
are equivalent will at some point just cause extra confusion for new
git users.
Elijah
From: Björn Steinbrink <hidden> Date: 2016-06-15 22:46:56
On 2009.06.09 16:42:33 -0400, Avery Pennarun wrote:
2009/6/9 Björn Steinbrink [off-list ref]:
quoted
On 2009.06.09 15:52:46 -0400, Avery Pennarun wrote:
quoted
To be honest, I'm not convinced svn's use of the word "revert" is
really right, though. Git's isn't *really* right either, since it
actually makes a new commit, it doesn't remove the old one like it
sounds like it does. Maybe 'reverse' would be a better name for what
git does, and we should just introduce another word for what svn does.
(With CVS, you just deleted the file and then did a checkout/update
on it again, which made sense to me. That works in git too.)
Crazy idea: we could actually make 'git revert' do both: given a
commit, it applies the reverse as it does now. Given filenames, it
simply brings them back to HEAD. But maybe that's too crazy.
Doesn't seem that crazy to me. But maybe a bit problematic if you want
to support both, "git checkout -- ." and "git checkout HEAD -- .". And
adding DWIMmery there seems dangerous, as in:
git revert == git checkout -- .
git revert HEAD ==
no uncommitted changes = revert commit HEAD
uncommitted changes = revert to HEAD
Well, that's what I meant by "crazy" :)
OK, thinking about it, I really dislike the idea of "revert --since",
as that is IMHO better thought of as "get the old version back", and for
"get something out of the repo" we have checkout. That would leave us
with "revert changes from a commit" and "revert uncommitted/unstaged
changes". For that "limited" thing, I could live with:
git revert <commit> # As is
git revert --unstaged # git checkout --
git revert --uncommitted # git checkout HEAD -- / git rm --cached
IOW: Mode of operation is chosen by a flag, which has a meaning that is
somewhat similar to --cached for diff/rm, it chooses what to use as the
source for the operation. And as at least "revert --uncommitted" isn't
100% the same as "checkout HEAD --", I think the overlap that we'd have
with a small subset of the checkout functionality might be ok.
Björn
From: Felipe Contreras <hidden> Date: 2016-06-15 22:46:56
On Tue, Jun 9, 2009 at 9:59 PM, Scott Chacon[off-list ref] wrote:
Hey all,
I have been playing with the EasyGit project lately and I have been
really impressed. I looked back to the last announcement here and the
conversation didn't really go anywhere, sadly. I thought it might be
nice to adopt or at least consider a number of the design decisions
they made in modifying the defaults and commands available. Perhaps
as a 1.7 goal or something? I like it because it addresses a lot of
the issues that I hear from beginning users:
* breaks the various things that 'checkout' does into separate
commands - moves 'revert' to doing what 'checkout -- path' does, moves
current 'revert' to 'cherry-pick --revert' (which someone mentioned
was a good idea at the last GitTogether), and adds 'unstage' for
'reset HEAD file'. also adds a '-s' option to 'branch' to switch to
the branch after you create it, which many people expect rather than
'checkout -b'.
I like 'git unstage', but not the rest.
* adds 'git resolved' for 'git add', which I hear all the time as
being confusing
I would prefer 'git stage'; 'git resolved' seems to be meant for a
very particular case: resolve conflicts, it would be much better to
learn that you can do 'git stage' at any time.
<snip/>
* 'git backout' for 'git reset HEAD^'
I don't like that. Looks like a very specialized case. It's much
better to learn this particular use of 'git reset'.
From: Felipe Contreras <hidden> Date: 2016-06-15 22:46:56
On Wed, Jun 10, 2009 at 7:03 AM, Linus
Torvalds[off-list ref] wrote:
On Tue, 9 Jun 2009, Theodore Tso wrote:
quoted
My personal opinion is this kind of overloading is actually more
confusing than simply adding a new name, such as "git revert-file".
I'd agree, except I think it actually worked pretty well in "git
checkout".
The alternative was to add yet another command for that, or to teach
people about the internal commands we did have. Adding the capability for
checkout to check out individual files - in addition to commits and
branches - I think worked pretty well.
Why? What makes 'git checkout <commit>' and 'git checkout <commit> --
<path>' similar at all? I would expect 'git checkout <commit>' to be
the same as 'git checkout <commit> -- .'
In my mind these are 2 completely different commands.
--
Felipe Contreras
On Wed, Jun 10, 2009 at 7:03 AM, Linus
Torvalds[off-list ref] wrote:
quoted
On Tue, 9 Jun 2009, Theodore Tso wrote:
quoted
My personal opinion is this kind of overloading is actually more
confusing than simply adding a new name, such as "git revert-file".
I'd agree, except I think it actually worked pretty well in "git
checkout".
The alternative was to add yet another command for that, or to teach
people about the internal commands we did have. Adding the capability for
checkout to check out individual files - in addition to commits and
branches - I think worked pretty well.
Why? What makes 'git checkout <commit>' and 'git checkout <commit> --
<path>' similar at all? I would expect 'git checkout <commit>' to be
the same as 'git checkout <commit> -- .'
You don't understand.
"git checkout" would be similar to "git revert", if we did that change.
IOW, both would be "if you give it a commit, it acts at a commit level",
and "if you give it pathnames, it acts on a pathname level".
That is totally obvious, and not in the least confusing. They are two
different things, but at the same time, there is no question about which
is which.
In my mind these are 2 completely different commands.
They are two different things, but they both make sense within the
_context_.
Only earthworms and FOX news have no concept of "in context". So it does
make sense to say "git checkout filename" (and expect it to check out that
_filename_ - surprise surprise), and also say "git checkout branch" (and
expect it to check out that branch - again, big surprise).
Humans are generally _very_ good at seeing the same word in two different
contexts, and not being confused at all. There is no confusion when I talk
about SCM's in the context of git, even though "SCM" could also mean a
Sceme interpreter, or "Saskatchewan College of Midwives".
In fact, it is often *much* better to accept context-awareness, than to
try too hard to be "uniquely identifying" even without context.
Of course, you do want things to also be unambiguous. But that's why we
have things like that "--" thing, when we want to specify pathspecs
explicitly and don't want to accept any kind of ambiguity. Most humans
tend to leave them out, and that "--" thing shows up mostly in git
scripts.
Linus
From: Scott Chacon <hidden> Date: 2016-06-15 22:46:56
Hey,
On Wed, Jun 10, 2009 at 4:04 PM, Linus
Torvalds[off-list ref] wrote:
IOW, both would be "if you give it a commit, it acts at a commit level",
and "if you give it pathnames, it acts on a pathname level".
That is totally obvious, and not in the least confusing. They are two
different things, but at the same time, there is no question about which
is which.
quoted
In my mind these are 2 completely different commands.
They are two different things, but they both make sense within the
_context_.
Only earthworms and FOX news have no concept of "in context". So it does
make sense to say "git checkout filename" (and expect it to check out that
_filename_ - surprise surprise), and also say "git checkout branch" (and
expect it to check out that branch - again, big surprise).
The problem here is that you're using 'check out' in your descriptions
of the expectations to mean two different things. One means 'switch
branches' and the other means 'extract content'. If you provide both
a branch and a filename, what happens? It still means 'extract
content'. Not everyone assumes that 'checkout' can or should mean
both of these things depending on context. I mean honestly, the
'context' of 'git checkout branch' and 'git checkout branch file'
doesn't really look that much different, but the command completely
switches semantics from 'switch active branch' to 'extract content'.
It's not that the command assumes some subtle defaults depending on
what arguments you give it - it's that it completely changes the
nature of what it does depending on the arguments. It only makes
sense to us because we specifically learned that it did this, not
because it makes sense intuitively. Hell, _neither_ of these meanings
are what SVN-inbound users are used to, which they map to 'extract
content _from a remote server_'.
Humans are generally _very_ good at seeing the same word in two different
contexts, and not being confused at all. There is no confusion when I talk
about SCM's in the context of git, even though "SCM" could also mean a
Sceme interpreter, or "Saskatchewan College of Midwives".
In fact, it is often *much* better to accept context-awareness, than to
try too hard to be "uniquely identifying" even without context.
This may be generally true for conversational language, but that
doesn't really cleanly apply here. If your vocabulary is only like 15
words (common porcelain commands), why would one of them be ambiguous
outside of context? Even given proper context, we're still being
arbitrary about how that command is interpreted - what if they wanted
to 'extract content' of all the files from another branch? Having
learned that 'git checkout <file>' extracts content of that file and
'git checkout <branch> <file>' extracts the contents of that file from
that branch, why wouldn't one assume that 'git checkout <branch>'
extracts the content of all the files in that branch? Wouldn't that
make more sense than arbitrarily doing something completely unrelated
('switching active branch')?
I'm not just arguing for arguments sake - I'm relaying from
individuals I'm trying to teach this to that they find it confusing.
This is not a theoretical argument, it is real world user feedback. I
probably struggled with things like this a bit at first and then
learned the idiosyncrasies of the tool and just accepted it like most
of the rest of us have - but many people honestly get confused and
frustrated by it. I see many of us helping people on IRC and whatnot
with this type of thing all the time.
I understand that clarity and ease of use is not really of primary
importance to this project. However, is it not slightly ironic that
the Git project is so obsessed with squeezing 5% or 10% of raw speed
out of each command, yet feels that the onus should be on each user to
study for hours to memorize a bunch of arbitrary idiosyncrasies of the
tool? Can we not obsess a little about flattening the learning curve
10% as well (possibly at the slight expense of command normalization
or verb bloat)?
Scott
From: Jakub Narebski <hidden> Date: 2016-06-15 22:46:56
Scott Chacon [off-list ref] writes:
On Wed, Jun 10, 2009 at 4:04 PM, Linus
Torvalds[off-list ref] wrote:
quoted
IOW, both would be "if you give it a commit, it acts at a commit level",
and "if you give it pathnames, it acts on a pathname level".
That is totally obvious, and not in the least confusing. They are two
different things, but at the same time, there is no question about which
is which.
quoted
In my mind these are 2 completely different commands.
They are two different things, but they both make sense within the
_context_.
Only earthworms and FOX news have no concept of "in context". So it does
make sense to say "git checkout filename" (and expect it to check out that
_filename_ - surprise surprise), and also say "git checkout branch" (and
expect it to check out that branch - again, big surprise).
The problem here is that you're using 'check out' in your descriptions
of the expectations to mean two different things. One means 'switch
branches' and the other means 'extract content'.
In both cases it means getting something out of repository (checking
out) and into working area.
If you provide both
a branch and a filename, what happens? It still means 'extract
content'.
If there is a filename, then it is checking out a file or files.
If there is no filename, then it is checking out a commit.
Checking out commit means switching branch if it is branch name,
detaching HEAD if it is not branch name.
When you are checking out a file or set of files, you cannot change
branch; commit is state of a whole project, not of individual files.
Not everyone assumes that 'checkout' can or should mean
both of these things depending on context. I mean honestly, the
'context' of 'git checkout branch' and 'git checkout branch file'
doesn't really look that much different, but the command completely
switches semantics from 'switch active branch' to 'extract content'.
Note that "git checkout <commit-ish>" was first (well, it was only
"git checkout <branch>" then.
It's not that the command assumes some subtle defaults depending on
what arguments you give it - it's that it completely changes the
nature of what it does depending on the arguments. It only makes
sense to us because we specifically learned that it did this, not
because it makes sense intuitively. Hell, _neither_ of these meanings
are what SVN-inbound users are used to, which they map to 'extract
content _from a remote server_'.
So perhaps _understanding_ those commands require understanding git
model. I don't see how this is a bad thing. You would have to learn
it anyway... ;-)
[...]
I understand that clarity and ease of use is not really of primary
importance to this project. However, is it not slightly ironic that
the Git project is so obsessed with squeezing 5% or 10% of raw speed
out of each command, yet feels that the onus should be on each user to
study for hours to memorize a bunch of arbitrary idiosyncrasies of the
tool? Can we not obsess a little about flattening the learning curve
10% as well (possibly at the slight expense of command normalization
or verb bloat)?
The problem is bakcward compatibility and the fact that git was not as
much as designed, as it has grown. Which is very good solution for
getting good feature set, but not so much for an UI...
--
Jakub Narebski
Poland
ShadeHawk on #git
From: Felipe Contreras <hidden> Date: 2016-06-15 22:46:56
On Thu, Jun 11, 2009 at 2:04 AM, Linus
Torvalds[off-list ref] wrote:
On Thu, 11 Jun 2009, Felipe Contreras wrote:
quoted
On Wed, Jun 10, 2009 at 7:03 AM, Linus
Torvalds[off-list ref] wrote:
quoted
On Tue, 9 Jun 2009, Theodore Tso wrote:
quoted
My personal opinion is this kind of overloading is actually more
confusing than simply adding a new name, such as "git revert-file".
I'd agree, except I think it actually worked pretty well in "git
checkout".
The alternative was to add yet another command for that, or to teach
people about the internal commands we did have. Adding the capability for
checkout to check out individual files - in addition to commits and
branches - I think worked pretty well.
Why? What makes 'git checkout <commit>' and 'git checkout <commit> --
<path>' similar at all? I would expect 'git checkout <commit>' to be
the same as 'git checkout <commit> -- .'
You don't understand.
"git checkout" would be similar to "git revert", if we did that change.
IOW, both would be "if you give it a commit, it acts at a commit level",
and "if you give it pathnames, it acts on a pathname level".
That is totally obvious, and not in the least confusing. They are two
different things, but at the same time, there is no question about which
is which.
I'm opposed to 'git revert -- <path>' for many reasons, one of which
is; you might want to grab some files that are in a future commit.
Reverting to the future is weird, unless you did a previous revert
backwards.
I do understand the two different 'git checkout' modes, that's not the
point, my point is the question you didn't answer; what does 'git
checkout <commit>' and 'git checkout -- <path>' have in common?
To me it seems the only thing they have in common is the name.
quoted
In my mind these are 2 completely different commands.
They are two different things, but they both make sense within the
_context_.
Only earthworms and FOX news have no concept of "in context". So it does
make sense to say "git checkout filename" (and expect it to check out that
_filename_ - surprise surprise), and also say "git checkout branch" (and
expect it to check out that branch - again, big surprise).
Humans are generally _very_ good at seeing the same word in two different
contexts, and not being confused at all. There is no confusion when I talk
about SCM's in the context of git, even though "SCM" could also mean a
Sceme interpreter, or "Saskatchewan College of Midwives".
Suppose you have a 'debian' branch, and a 'debian' directory, what
does this command do?
git checkout debian
Sure, I'm not an earthworm, so I can guess that command means checkout
the debian branch because it's a much more common action. But git
doesn't know that, you need to do:
git checkout debian --
If I know I want to checkout a branch I would like to do:
git <command to checkout a branch> debian
In fact, it is often *much* better to accept context-awareness, than to
try too hard to be "uniquely identifying" even without context.
Of course, you do want things to also be unambiguous. But that's why we
have things like that "--" thing, when we want to specify pathspecs
explicitly and don't want to accept any kind of ambiguity. Most humans
tend to leave them out, and that "--" thing shows up mostly in git
scripts.
Yeah, unless git finds it ambiguous and the user is forced to learn a
new idiom in order to get rid of the ambiguity.
--
Felipe Contreras
From: Felipe Contreras <hidden> Date: 2016-06-15 22:46:56
On Thu, Jun 11, 2009 at 3:15 AM, Jakub Narebski[off-list ref] wrote:
Scott Chacon [off-list ref] writes:
quoted
On Wed, Jun 10, 2009 at 4:04 PM, Linus
Torvalds[off-list ref] wrote:
quoted
IOW, both would be "if you give it a commit, it acts at a commit level",
and "if you give it pathnames, it acts on a pathname level".
That is totally obvious, and not in the least confusing. They are two
different things, but at the same time, there is no question about which
is which.
quoted
In my mind these are 2 completely different commands.
They are two different things, but they both make sense within the
_context_.
Only earthworms and FOX news have no concept of "in context". So it does
make sense to say "git checkout filename" (and expect it to check out that
_filename_ - surprise surprise), and also say "git checkout branch" (and
expect it to check out that branch - again, big surprise).
The problem here is that you're using 'check out' in your descriptions
of the expectations to mean two different things. One means 'switch
branches' and the other means 'extract content'.
In both cases it means getting something out of repository (checking
out) and into working area.
'git reset' also gets something out of the repository and into the
working area, that's not reason enough to put them under the same
'checkout' command, is it?
[...]
quoted
I understand that clarity and ease of use is not really of primary
importance to this project. However, is it not slightly ironic that
the Git project is so obsessed with squeezing 5% or 10% of raw speed
out of each command, yet feels that the onus should be on each user to
study for hours to memorize a bunch of arbitrary idiosyncrasies of the
tool? Can we not obsess a little about flattening the learning curve
10% as well (possibly at the slight expense of command normalization
or verb bloat)?
The problem is bakcward compatibility and the fact that git was not as
much as designed, as it has grown. Which is very good solution for
getting good feature set, but not so much for an UI...
Backwards compatibility must be broken at some point or another,
otherwise people will start to create their own aliases, alternative
UI's and even forks. Sure, it must be done carefully and planned in
advance, that's why it's a good idea to keep a list of things to
change in the next interface break.
--
Felipe Contreras
From: Jakub Narebski <hidden> Date: 2016-06-15 22:46:56
On Thu, 11 June 2009, Felipe Contreras wrote:
On Thu, Jun 11, 2009 at 3:15 AM, Jakub Narebski[off-list ref] wrote:
quoted
Scott Chacon [off-list ref] writes:
quoted
On Wed, Jun 10, 2009 at 4:04 PM, Linus
Torvalds[off-list ref] wrote:
quoted
IOW, both would be "if you give it a commit, it acts at a commit level",
and "if you give it pathnames, it acts on a pathname level".
That is totally obvious, and not in the least confusing. They are two
different things, but at the same time, there is no question about which
is which.
quoted
In my mind these are 2 completely different commands.
They are two different things, but they both make sense within the
_context_.
Only earthworms and FOX news have no concept of "in context". So it does
make sense to say "git checkout filename" (and expect it to check out that
_filename_ - surprise surprise), and also say "git checkout branch" (and
expect it to check out that branch - again, big surprise).
The problem here is that you're using 'check out' in your descriptions
of the expectations to mean two different things. One means 'switch
branches' and the other means 'extract content'.
In both cases it means getting something out of repository (checking
out) and into working area.
'git reset' also gets something out of the repository and into the
working area, that's not reason enough to put them under the same
'checkout' command, is it?
Nope. 'git reset' resets something to the state in repository (to given
commit). The fact that some combination of options for 'git reset' gives
the same result as some specific combination of options of 'git checkout'
means only that one can arrive at some destination in two different ways.
--
Jakub Narebski
Poland
From: Felipe Contreras <hidden> Date: 2016-06-15 22:46:56
On Thu, Jun 11, 2009 at 3:42 AM, Jakub Narebski[off-list ref] wrote:
On Thu, 11 June 2009, Felipe Contreras wrote:
quoted
On Thu, Jun 11, 2009 at 3:15 AM, Jakub Narebski[off-list ref] wrote:
quoted
Scott Chacon [off-list ref] writes:
quoted
On Wed, Jun 10, 2009 at 4:04 PM, Linus
Torvalds[off-list ref] wrote:
quoted
IOW, both would be "if you give it a commit, it acts at a commit level",
and "if you give it pathnames, it acts on a pathname level".
That is totally obvious, and not in the least confusing. They are two
different things, but at the same time, there is no question about which
is which.
quoted
In my mind these are 2 completely different commands.
They are two different things, but they both make sense within the
_context_.
Only earthworms and FOX news have no concept of "in context". So it does
make sense to say "git checkout filename" (and expect it to check out that
_filename_ - surprise surprise), and also say "git checkout branch" (and
expect it to check out that branch - again, big surprise).
The problem here is that you're using 'check out' in your descriptions
of the expectations to mean two different things. One means 'switch
branches' and the other means 'extract content'.
In both cases it means getting something out of repository (checking
out) and into working area.
'git reset' also gets something out of the repository and into the
working area, that's not reason enough to put them under the same
'checkout' command, is it?
Nope. 'git reset' resets something to the state in repository (to given
commit). The fact that some combination of options for 'git reset' gives
the same result as some specific combination of options of 'git checkout'
means only that one can arrive at some destination in two different ways.
You can describe what 'git reset' does in many ways, but in the
process it's still getting something out of the repository and into
the working directory, does it not? 'git checkout <commitish>' and
'git checkout <commitish> -- <path>' also do that.
Is that relevant? No. What is relevant is the final action the user is
expecting to achieve.
Therefore, the fact that 'git checkout <commitish>' modifies the
working directory is irrelevant, it's still doing an extra step;
update HEAD, and that final action is what is important for this
particular command; it switches to another commitish.
--
Felipe Contreras
From: Jakub Narebski <hidden> Date: 2016-06-15 22:46:56
On Fri, 12 Jun 2009, Felipe Contreras wrote:
On Thu, Jun 11, 2009 at 3:42 AM, Jakub Narebski[off-list ref] wrote:
quoted
On Thu, 11 June 2009, Felipe Contreras wrote:
quoted
quoted
'git reset' also gets something out of the repository and into the
working area, that's not reason enough to put them under the same
'checkout' command, is it?
Nope. 'git reset' resets something to the state in repository (to given
commit). The fact that some combination of options for 'git reset' gives
the same result as some specific combination of options of 'git checkout'
means only that one can arrive at some destination in two different ways.
You can describe what 'git reset' does in many ways, but in the
process it's still getting something out of the repository and into
the working directory, does it not? 'git checkout <commitish>' and
'git checkout <commitish> -- <path>' also do that.
Nope. 'git reset' always reset some part of state to a given commit,
HEAD by default. It can reset current branch with --soft, branch plus
index with --mixed (default), and branch plus index plus working
directory with --hard. Source is always commit.
'git checkout' however checks out something into working directory.
It can be branch, in which turns it sets HEAD to point to it, and
index too. It can be file, in which it gets version of file from
index or (if specified) from given commit. Destination is always
working area (and sometimes something else beside it).
Is that relevant? No. What is relevant is the final action the user is
expecting to achieve.
Therefore, the fact that 'git checkout <commitish>' modifies the
working directory is irrelevant, it's still doing an extra step;
update HEAD, and that final action is what is important for this
particular command; it switches to another commitish.
It is not uncommon for a word to have different meaning depending on
context, or on some auxiliary word used in addition...
--
Jakub Narebski
Poland
From: Felipe Contreras <hidden> Date: 2016-06-15 22:46:56
On Sat, Jun 13, 2009 at 12:21 AM, Jakub Narebski[off-list ref] wrote:
On Fri, 12 Jun 2009, Felipe Contreras wrote:
quoted
On Thu, Jun 11, 2009 at 3:42 AM, Jakub Narebski[off-list ref] wrote:
quoted
On Thu, 11 June 2009, Felipe Contreras wrote:
quoted
quoted
quoted
'git reset' also gets something out of the repository and into the
working area, that's not reason enough to put them under the same
'checkout' command, is it?
Nope. 'git reset' resets something to the state in repository (to given
commit). The fact that some combination of options for 'git reset' gives
the same result as some specific combination of options of 'git checkout'
means only that one can arrive at some destination in two different ways.
You can describe what 'git reset' does in many ways, but in the
process it's still getting something out of the repository and into
the working directory, does it not? 'git checkout <commitish>' and
'git checkout <commitish> -- <path>' also do that.
Nope. 'git reset' always reset some part of state to a given commit,
HEAD by default. It can reset current branch with --soft, branch plus
index with --mixed (default), and branch plus index plus working
directory with --hard. Source is always commit.
You said it: 'git reset --hard' gets something out of the repository
and into the working directory.
Try this:
git checkout <random sha-1 with no ref>
Then what is the difference between:
git checkout HEAD^
git reset --hard HEAD^
In this case they do exactly the same thing, don't they?
'git checkout' however checks out something into working directory.
It can be branch, in which turns it sets HEAD to point to it, and
index too. It can be file, in which it gets version of file from
index or (if specified) from given commit. Destination is always
working area (and sometimes something else beside it).
quoted
Is that relevant? No. What is relevant is the final action the user is
expecting to achieve.
Therefore, the fact that 'git checkout <commitish>' modifies the
working directory is irrelevant, it's still doing an extra step;
update HEAD, and that final action is what is important for this
particular command; it switches to another commitish.
It is not uncommon for a word to have different meaning depending on
context, or on some auxiliary word used in addition...
We are talking about a command here, not a command that has two slight
variations of the same main action, a command that is doing *two*
completely unrelated actions depending on the context.
Think about these 3 actions:
a) get a path out of a commit in the repository and into the working directory
b) switch to another commit, reseting the working directory
c) reset current branch to certain commit, and checkout into the
working directory
The 3 actions require putting something into the working directory;
what makes a) and b) so similar they belong to the same command?
--
Felipe Contreras
From: Jakub Narebski <hidden> Date: 2016-06-15 22:46:56
On Fri, 12 Jun 2009, Felipe Contreras wrote:
On Sat, Jun 13, 2009 at 12:21 AM, Jakub Narebski[off-list ref] wrote:
quoted
Nope. 'git reset' always reset some part of state to a given commit,
HEAD by default. It can reset current branch with --soft, branch plus
index with --mixed (default), and branch plus index plus working
directory with --hard. Source is always commit.
You said it: 'git reset --hard' gets something out of the repository
and into the working directory.
Try this:
git checkout <random sha-1 with no ref>
Then what is the difference between:
git checkout HEAD^
git reset --hard HEAD^
In this case they do exactly the same thing, don't they?
No, they don't. "git checkout HEAD^" modifies HEAD detaching it.
"git reset --hard HEAD^" modifies branch that HEAD points to (well,
unless HEAD is detached).
--
Jakub Narebski
Poland
From: Felipe Contreras <hidden> Date: 2016-06-15 22:46:56
On Sat, Jun 13, 2009 at 1:05 AM, Jakub Narebski[off-list ref] wrote:
On Fri, 12 Jun 2009, Felipe Contreras wrote:
quoted
On Sat, Jun 13, 2009 at 12:21 AM, Jakub Narebski[off-list ref] wrote:
quoted
quoted
Nope. 'git reset' always reset some part of state to a given commit,
HEAD by default. It can reset current branch with --soft, branch plus
index with --mixed (default), and branch plus index plus working
directory with --hard. Source is always commit.
You said it: 'git reset --hard' gets something out of the repository
and into the working directory.
Try this:
git checkout <random sha-1 with no ref>
Then what is the difference between:
git checkout HEAD^
git reset --hard HEAD^
In this case they do exactly the same thing, don't they?
No, they don't. "git checkout HEAD^" modifies HEAD detaching it.
"git reset --hard HEAD^" modifies branch that HEAD points to (well,
unless HEAD is detached).
Read again:
quoted
git checkout <random sha-1 with no ref>
The HEAD is detached, so they do exactly the same in this case.
--
Felipe Contreras
From: Björn Steinbrink <hidden> Date: 2016-06-15 22:46:56
On 2009.06.13 01:30:38 +0300, Felipe Contreras wrote:
On Sat, Jun 13, 2009 at 1:05 AM, Jakub Narebski[off-list ref] wrote:
quoted
On Fri, 12 Jun 2009, Felipe Contreras wrote:
quoted
On Sat, Jun 13, 2009 at 12:21 AM, Jakub Narebski[off-list ref] wrote:
quoted
quoted
Nope. 'git reset' always reset some part of state to a given commit,
HEAD by default. It can reset current branch with --soft, branch plus
index with --mixed (default), and branch plus index plus working
directory with --hard. Source is always commit.
You said it: 'git reset --hard' gets something out of the repository
and into the working directory.
Try this:
git checkout <random sha-1 with no ref>
Then what is the difference between:
git checkout HEAD^
git reset --hard HEAD^
In this case they do exactly the same thing, don't they?
No, they don't. "git checkout HEAD^" modifies HEAD detaching it.
"git reset --hard HEAD^" modifies branch that HEAD points to (well,
unless HEAD is detached).
Read again:
quoted
quoted
git checkout <random sha-1 with no ref>
The HEAD is detached, so they do exactly the same in this case.
Not if there are uncommitted changes to tracked files.
Björn