
We have always had a nice way to reset a working tree to another state while carrying our changes around: "git read-tree -u -m". Yes, it fails if the target tree is different in the paths that are dirty in the working tree, but this is how we used to switch branches in "git checkout", and it worked fine. However, perhaps exactly _because_ we've supported this from very early on, another low-level command, namely "git reset", never did. But as time went on, 'git reset' remains as a very common command, while 'git read-tree' is now a very odd and low-level plumbing thing that nobody sane should ever use, because it only makes sense together with other operations like either switching branches or just rewriting HEAD. Which means that we have effectively lost the ability to do something very common: jump to another point in time without always dropping all our dirty state. So add this kind of mode to "git reset", and since it merges your changes to what you are resetting to, just call it that: "git reset --merge". I've wanted this for a long time, since I very commonly carry a dirty tree while working on things. My main 'Makefile' file quite often has the next version already modified, and sometimes I have local modifications that I don't want to commit, but I still do pulls and patch applications, and occasionally want to do "git reset" to undo them - while still keeping my local modifications. (Maybe we could eventually change it to something like "if we have a working tree, default to --merge, otherwise default to --mixed"). NOTE! This new mode is certainly not perfect. There's a few things to look out for: - if the index has unmerged entries, "--merge" will currently simply refuse to reset ("you need to resolve your current index first"). You'll need to use "--hard" or similar in this case. This is sad, because normally a unmerged index means that the working tree file should have matched the source tree, so the correct action is likely to make --merge reset such a path to the target (like --hard), regardless of dirty state in-tree or in-index. But that's not how read-tree has ever worked, so.. - "git checkout -m" actually knows how to do a three-way merge, rather than refuse to update the working tree. So we do know how to do that, and arguably that would be even nicer behavior. At the same time it's also arguably true that there is a chance of loss of state (ie you cannot get back to the original tree if the three-way merge ends up resolving cleanly to no diff at all), so the "refuse to do it" is in some respects the safer - but less user-friendly - option. In other words, I think 'git reset --merge' could become a bit more friendly, but this is already a big improvement. It allows you to undo a recent commit without having to throw your current work away. Yes, yes, with a dirty tree you could always do git stash git reset --hard git stash apply instead, but isn't "git reset --merge" a nice way to handle one particular simple case? Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> -- Hmm? Maybe I'm the only one that does a lot of work with a dirty tree, and sure, I can do other things like the "git stash" thing, or using "git checkout" to actually create a new branch, and then playing games with branch renaming etc to make it work like this one. But I suspect others dislike how "git reset" works too. But see the suggested improvements above. builtin-reset.c | 26 ++++++++++++++++++-------- 1 files changed, 18 insertions(+), 8 deletions(-)
…
…
…
…
//////////////////////////////////////////////////////////////// GIT - the stupid content tracker //////////////////////////////////////////////////////////////// "git" can mean anything, depending on your mood. - random three-letter combination that is pronounceable, and not actually used by any common UNIX command. The fact that it is a mispronunciation of "get" may or may not be relevant. - stupid. contemptible and despicable. simple. Take your pick from the dictionary of slang. - "global information tracker": you're in a good mood, and it actually works for you. Angels sing, and a light suddenly fills the room. - "goddamn idiotic truckload of sh*t": when it breaks Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals. Git is an Open Source project covered by the GNU General Public License. It was originally written by Linus Torvalds with help of a group of hackers around the net. It is currently maintained by Junio C Hamano. Please read the file INSTALL for installation instructions. See Documentation/tutorial.txt to get started, then see Documentation/everyday.txt for a useful minimum set of commands, and "man git-commandname" for documentation of each command. CVS users may also want to read Documentation/cvs-migration.txt. Many Git online resources are accessible from http://git.or.cz/ including full documentation and Git related tools. The user discussion and development of Git take place on the Git mailing list -- everyone is welcome to post bug reports, feature requests, comments and patches to git@vger.kernel.org. To subscribe to the list, send an email with just "subscribe git" in the body to majordomo@vger.kernel.org. The mailing list archives are available at http://marc.theaimsgroup.com/?l=git and other archival sites. The messages titled "A note from the maintainer", "What's in git.git (stable)" and "What's cooking in git.git (topics)" and the discussion following them on the mailing list give a good reference for project status, development direction and remaining tasks.
Description
Git with broken hash generation to generate collisions between object IDs. Don't use this!
https://undefinedbehavior.de/posts/commit-vandalism/
Languages
C
50%
Shell
38.2%
Perl
5.5%
Tcl
3.5%
Python
0.9%
Other
1.7%