From: David Jeske <hidden> Date: 2016-08-14 00:45:54
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>
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
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
quoted
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
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
From: Jakub Narebski <hidden> Date: 2016-06-15 22:44:49
Boaz Harrosh [off-list ref] 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
From: David Jeske <hidden> Date: 2016-06-15 22:44:49
-- David Jeske wrote:
quoted
- 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.
- 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
From: Steven Walter <hidden> Date: 2016-06-15 22:44:49
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 [off-list ref]
Freedom is the freedom to say that 2 + 2 = 4
B2F1 0ECC E605 7321 E818 7A65 FC81 9777 DC28 9E8F
From: Steven Walter <hidden> Date: 2016-06-15 22:44:49
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 <redacted>
---
builtin-reset.c | 24 +++++++++++++++++++++++-
1 files changed, 23 insertions(+), 1 deletions(-)
@@ -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*atall,butrequirestheminagoodorder.Otherresetsreset*theindexfiletothetreeobjectweareswitchingto.*/
From: Junio C Hamano <hidden> Date: 2016-06-15 22:44:49
Steven Walter [off-list ref] writes:
quoted hunk
@@ -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.
From: David Jeske <hidden> Date: 2016-06-15 22:44:49
-- 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.
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
From: Johannes Gilger <hidden> Date: 2016-06-15 22:44:49
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 [off-list ref]
http://hackvalue.de/heipei/
GPG-Key: 0x42F6DE81
GPG-Fingerprint: BB49 F967 775E BB52 3A81 882C 58EE B178 42F6 DE81
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
@@ -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
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:44:49
Hi,
just to add to Junio's comments:
On Wed, 25 Jun 2008, Boaz Harrosh wrote:
Junio C Hamano wrote:
quoted
Steven Walter [off-list ref] writes:
quoted
@@ -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.
quoted
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
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
From: Johannes Sixt <hidden> Date: 2016-06-15 22:44:49
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
From: Anton Gladkov <hidden> Date: 2016-06-15 22:44:49
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:
quoted
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
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:44:49
Hi,
On Wed, 25 Jun 2008, Anton Gladkov wrote:
On Wed, Jun 25, 2008 at 02:24:58PM +0400, Matthias Kestenholz wrote:
quoted
On Wed, 2008-06-25 at 11:16 +0100, Johannes Schindelin wrote:
quoted
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
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:44:49
Hi,
On Wed, 25 Jun 2008, Johannes Sixt wrote:
Johannes Schindelin schrieb:
quoted
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
On Wed, 25 Jun 2008 at 12:12pm +0300, Boaz Harrosh wrote:
Junio C Hamano wrote:
quoted
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
On Wed, Jun 25, 2008 at 01:38:30PM +0100, Johannes Schindelin wrote:
quoted
$ 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
From: Craig L. Ching <hidden> Date: 2016-06-15 22:44:49
-----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
--
From: Anton Gladkov <hidden> Date: 2016-06-15 22:44:49
On Wed, Jun 25, 2008 at 06:49:16PM +0400, Craig L. Ching wrote:
quoted
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
From: Andreas Ericsson <hidden> Date: 2016-06-15 22:44:50
Boaz Harrosh wrote:
Junio C Hamano wrote:
quoted
Steven Walter [off-list ref] writes:
quoted
@@ -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.
quoted
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
From: Jon Loeliger <hidden> Date: 2016-06-15 22:44:50
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
From: David Jeske <hidden> Date: 2016-08-14 00:43:07
-- David Jeske wrote:
quoted
- 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.
From: David Jeske <hidden> Date: 2016-08-14 00:43:08
-- 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.