LWN: Comments on " Apache Subversion 1.11.0 released" https://lwn.net/Articles/770134/ This is a special feed containing comments posted to the individual LWN article titled " Apache Subversion 1.11.0 released". en-us Sat, 01 Nov 2025 09:53:14 +0000 Sat, 01 Nov 2025 09:53:14 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Hmm … https://lwn.net/Articles/772346/ https://lwn.net/Articles/772346/ moltonel <div class="FormattedComment"> In this case they're not too hard to find, I know I tried them myself to solve the "work with multiple branches in parallel" problem. It's just that they all have drawbacks and in the end, `cp -a` works better for me.<br> <p> It's worse with the "proper file rename support" problem though: in that case all the experts had to propose were ways to split/group two rename/modify commits together, which are not only horribly complicated, but don't solve the actual problem. The workaround of separating commits into a "pure rename commit" and "the rest of the commit" (whatever the level of automation) is really not satisfying.<br> </div> Sat, 17 Nov 2018 11:02:24 +0000 Hmm … https://lwn.net/Articles/772305/ https://lwn.net/Articles/772305/ aleXXX <div class="FormattedComment"> Here we see one issue of git in action.<br> Somebody raises an issue or question, and thi starts a discussion between git experts who all propose different non-obvious git commands.<br> <p> </div> Fri, 16 Nov 2018 22:47:16 +0000 Hmm … https://lwn.net/Articles/771854/ https://lwn.net/Articles/771854/ mathstuf <div class="FormattedComment"> It's just used during `git rebase` (AFAIK). It stores your local diffs until the rebase is over and then applies them (keeping them in the stash if there are conflicts). It also comes into play when using `git pull --rebase`.<br> </div> Wed, 14 Nov 2018 15:28:39 +0000 Hmm … https://lwn.net/Articles/771792/ https://lwn.net/Articles/771792/ jezuch <div class="FormattedComment"> There *is* autostash but I haven't used it so I don't know what it does or when :)<br> </div> Wed, 14 Nov 2018 08:29:49 +0000 Hmm … https://lwn.net/Articles/771765/ https://lwn.net/Articles/771765/ arnout <div class="FormattedComment"> <font class="QuotedText">&gt; No, what I mean is when you 'rm' a file or two in the working copy and then you want to restore those files</font><br> <font class="QuotedText">&gt; from the current commit (or from git's index, if they happen to be in there).</font><br> <p> You might want to give 'git checkout -p' a try.<br> <p> <p> </div> Tue, 13 Nov 2018 22:51:22 +0000 Hmm … https://lwn.net/Articles/771577/ https://lwn.net/Articles/771577/ mathstuf <div class="FormattedComment"> <font class="QuotedText">&gt; (FWIW, I've (ab?)used this property of git to great effect in some projects, e.g. tracking an automatically modified version of one tree in another, where you just have to provide a tree-&gt;tree mapping "function", and then git will sort out everything else basically by itself)</font><br> <p> This is what we do to track third-party library imports in our projects. We take the upstream tree, select out files we want and then `git merge -Xsubtree=import/path/` into the "right place" in the project tree. There are then commit checks to ensure that all changes do that subdirectory are done via the importing process.<br> </div> Mon, 12 Nov 2018 16:26:15 +0000 Hmm … https://lwn.net/Articles/771576/ https://lwn.net/Articles/771576/ mathstuf <div class="FormattedComment"> I'd say you just give it to `git bisect start`. Offhand, I imagine it could basically treat all non-first-parent commits as `skip`. When it finds out that it is one of the X auto-skipped commits, it unmarks the first-parent history of those candidate commits and then restarts the bisect on those commits.<br> </div> Mon, 12 Nov 2018 16:24:05 +0000 Hmm … https://lwn.net/Articles/771469/ https://lwn.net/Articles/771469/ smurf <div class="FormattedComment"> <font class="QuotedText">&gt; which makes me wonder....</font><br> <p> If you only do first-parent then you may end up at the point where your only possible refinement is to start bisecting a group, which you forbade git to do – after all, you used "--first-parent".<br> <p> Thus, this situation requires additional code – which hasn't been implemented yet.<br> </div> Mon, 12 Nov 2018 08:26:26 +0000 Hmm … https://lwn.net/Articles/771458/ https://lwn.net/Articles/771458/ neilbrown <div class="FormattedComment"> <font class="QuotedText">&gt; I think this would be handled well with a `git bisect --first-parent` option ...</font><br> <p> What version of git do you need? Do you give "--first-parent" when you "git bisect start" or on every "git bisect good/bad"??<br> <p> "revision.c" in current git contains the line<br> <p> revision.c: die(_("--first-parent is incompatible with --bisect"));<br> <p> which makes me wonder....<br> <p> </div> Mon, 12 Nov 2018 04:17:55 +0000 Hmm … https://lwn.net/Articles/771443/ https://lwn.net/Articles/771443/ neilbrown <div class="FormattedComment"> <font class="QuotedText">&gt; And how is that going to help us noobs (who don't have a great understanding of git)?</font><br> <p> The best way to help noobs like you is through education.<br> An important part of education is encouraging exploration and experimentation.<br> <p> If something goes wrong and you try to fix it up and fail, and then post in some community "Hi, X happened so I tried Y and now Z", then someone says "Oh no, never try Y - that is a disaster, I hope you have backups" - then you might not want to experiment again.<br> If, instead, they could say "Y probably wasn't the best approach, but git has your back - just run this simple command and look through the resulting log until you see the code you lost - then do Q to recover it" - you might be more likely to experiment more next time.<br> <p> So I agree that auto-git-stash is not a complete solution, but it does seem that it would still be valuable.<br> <p> </div> Sun, 11 Nov 2018 21:59:10 +0000 Hmm … https://lwn.net/Articles/771434/ https://lwn.net/Articles/771434/ jezuch <div class="FormattedComment"> I agree that names could be better. This is one more illustration of evolution over intelligent design ;) But after a while of using git it's all just... identifiers.<br> </div> Sun, 11 Nov 2018 18:37:28 +0000 Hmm … https://lwn.net/Articles/771432/ https://lwn.net/Articles/771432/ Wol <div class="FormattedComment"> And how is that going to help us noobs (who don't have a great understanding of git)?<br> <p> I tend to use git with a bit of a cookbook aide-memoir, I have an understanding of what's going on but it's not particularly good. An automatic "git stash" will be a pretty good way of helping me lose stuff, because I haven't yet got to grips with what stash actually does. Yes I know it puts stuff "somewhere safe", but as it is at home, "somewhere safe" usually equates to "I've forgotten where I put it" ie I've lost it.<br> <p> Cheers,<br> Wol<br> </div> Sun, 11 Nov 2018 17:58:26 +0000 Hmm … https://lwn.net/Articles/771361/ https://lwn.net/Articles/771361/ flussence <div class="FormattedComment"> I once spent some time using git-svn to work with an ancient subversion server (for practical reasons - the git clone was much smaller on disk and `git commit` was about 15 minutes faster than `svn ci`).<br> <p> That didn't last unfortunately; somehow it led to the svn server writing corrupt metadata to its own DB that it couldn't read, and I ended up spending a day to repair it by hand.<br> <p> (Maybe this anecdote says more about the working conditions at that gig than SVN, but it was still an unpleasant bug to run into.)<br> </div> Fri, 09 Nov 2018 22:07:44 +0000 Hmm … https://lwn.net/Articles/771351/ https://lwn.net/Articles/771351/ mathstuf <div class="FormattedComment"> We do this by having a `Backport: &lt;branch&gt;` trailer in the description of the merge request which the merge robot then takes and merges into the required branches. The full syntax is `Backport: branch:committish` where `HEAD` is replaced by the commit at the top of the MR. Need to resolve a conflict? Merge on your MR branch and then do `Backport: release:HEAD^2` to get the release fix into that branch.<br> </div> Fri, 09 Nov 2018 19:55:37 +0000 Hmm … https://lwn.net/Articles/771350/ https://lwn.net/Articles/771350/ mathstuf <div class="FormattedComment"> One class in college had a shared SVN repo for the whole class. Some enterprising soul managed to commit `.svn` to the repo. How? I have no idea. But the server was decided unhappy with the situation.<br> </div> Fri, 09 Nov 2018 19:53:39 +0000 Hmm … https://lwn.net/Articles/771349/ https://lwn.net/Articles/771349/ mathstuf <div class="FormattedComment"> <font class="QuotedText">&gt; 'git bisect' could become aware of groups (bisecting at top-level granularity first, then optionally breaking down to the next level to find the particular sub-commit</font><br> <p> I think this would be handled well with a `git bisect --first-parent` option which bisects the first-parent history and then starts bisecting the history between the two commits recursively on the remaining history using the same first-parent semantics. Then your "groupings" are exactly merges.<br> </div> Fri, 09 Nov 2018 19:52:20 +0000 Hmm … https://lwn.net/Articles/770917/ https://lwn.net/Articles/770917/ Wol <div class="FormattedComment"> <font class="QuotedText">&gt; There is no such thing as a branch in SVN; by convention only, the root of the repository contains three directories, "tags", "branches" and "trunk". You are quite at liberty to check out the root and thus have all branches plus all tags plus trunk in a single working copy, and to commit a single commit across branches, tags and trunk at once. </font><br> <p> Problem is, there's no such thing as a root in git. That's the whole point of a DVCS :-) The only reason Linus' tree is the root for linux is that everybody agrees that it is.<br> <p> Having worked with Visual Sourcesafe, and with git, git is so much simpler because you're not stepping on other peoples' toes all the time :-)<br> <p> Cheers,<br> Wol<br> </div> Wed, 07 Nov 2018 13:53:01 +0000 Hmm … https://lwn.net/Articles/770914/ https://lwn.net/Articles/770914/ jezuch <div class="FormattedComment"> If there is only one line changed then git will almost certainly get this right, unless the file is very small. The heuristic is configurable, also, and the default for the "effort" parameter (don't remember what it's actually called) is too small in my opinion. I always jack it up way, way higher.<br> <p> AFAICT the git developers will refuse addition of an explicit rename on the grounds that it's an "information tracker" and in theory it could also highlight code moved around in other ways. On the other hand the most recent release will also figure out that an entire directory was renamed, so if you add a file into that directory on one branch and rename the directory on another, when you merge these branches the newly added file will also be moved along with the rest of the files in that directory. It used to drive me nuts when I did merges like this in the past :)<br> </div> Wed, 07 Nov 2018 11:12:14 +0000 Hmm … commit groups https://lwn.net/Articles/770889/ https://lwn.net/Articles/770889/ neilbrown <div class="FormattedComment"> From a pragmatic perspective (rather than aesthetic) you seem to have identified two particular elements of functionality.<br> <p> For the moment I'm thinking of a group as a merge commit plus all the commits on the right side of the merge that aren't also on the left (for some reasonable understanding of "left" and "right").<br> <p> 1/ you want "git bisect" to recognise these merge points and preferentially test those, rather than commits on the right. I suspect it would be fairly easy to do this for all merges. It would be expected to increase the number of steps a little, but probably just by one or two.<br> <p> 2/ you want to allow a new commit to mark an existing commit as part of it's group. This is comparatively huge. For git-bisect to be able to notice, you would need to create some sort of index from child commits back to their parents, at least for merged commits.<br> Between 4.1 and 4.19 (just a random sample) there are 20808 merge commits and 232659 non-merges. That means about 10% of commits are merges. Adding an index for the children of all merges should be manageable. If it was just "all merges with some magic string in the message" it would be even more manageable. I'm not sure if that is quite enough to allow git-bisect to do what we want.<br> <p> I've occasionally thought this would be good for patches labeled "Fixes:". If they were attached to the patch they fix in a way that git-bisect could detect, then maybe it could always pull in fix - or a least warn that a fix was missing.<br> <p> I think there are ideas worth exploring here (if only I had the time).<br> <p> </div> Tue, 06 Nov 2018 23:02:05 +0000 Hmm … https://lwn.net/Articles/770877/ https://lwn.net/Articles/770877/ neilbrown <div class="FormattedComment"> <font class="QuotedText">&gt; It's more about 'git checkout .' which will silently overwrite every local change in the working copy.</font><br> <p> Anyone want to write a patch which causes "git checkout" (and anything else potentially destructive) to do an automatic "git stash" first ???<br> <p> </div> Tue, 06 Nov 2018 20:14:03 +0000 Hmm … https://lwn.net/Articles/770876/ https://lwn.net/Articles/770876/ epa <div class="FormattedComment"> Yes, that's the core of my complaint: it sounds a lot more innocuous than it is. If it were called 'git overwrite-local-changes' there wouldn't be any issue. I think that being called 'checkout' it should prompt a bit more before trashing multiple files.<br> </div> Tue, 06 Nov 2018 20:09:38 +0000 Hmm … https://lwn.net/Articles/770875/ https://lwn.net/Articles/770875/ epa <div class="FormattedComment"> Thanks! <br> </div> Tue, 06 Nov 2018 20:08:01 +0000 Hmm … https://lwn.net/Articles/770872/ https://lwn.net/Articles/770872/ MrWim <p>Put this in <code>git-group.sh</code>, mark it executable and run <code>git config --global alias.group '!/path/to/git-group.sh'</code>. You will then be able to run <code>git group open</code> and <code>git group close</code>. It's a quick and dirty hack, with precious little error handling, but it will support nesting and should be convenient to use.</p> <p>If you want to get a log with these groups collapsed run <code>git log --first-parent</code>.</p> <p><code>git-group.sh</code> follows:</p> <pre> #!/bin/sh -e fail() { echo $@ &gt;&amp;2 exit 1 } current_branch=$(git symbolic-ref --short HEAD) cmd=$1 shift case &quot;$cmd&quot; in open) git checkout -b ${current_branch}-group ;; close) parent=$(echo $current_branch | sed 's/-group$//') [ &quot;$parent&quot; != &quot;$current_branch&quot; ] || fail &quot;Not in a group!&quot; git checkout &quot;$parent&quot; git merge --no-ff --no-commit --log &quot;$current_branch&quot; --edit printf '# Enter top-level commit message here. Sub-commit messages follow:\n\n' &gt;.group_commit_msg git log --first-parent --format=%B &quot;${parent}...${current_branch}&quot; &gt;&gt;.group_commit_msg git commit --file .group_commit_msg --edit rm .group_commit_msg git branch -D &quot;$current_branch&quot; ;; *) fail &quot;Unknown command $cmd&quot; ;; esac </pre> Tue, 06 Nov 2018 19:44:40 +0000 Hmm … https://lwn.net/Articles/770838/ https://lwn.net/Articles/770838/ jezuch <div class="FormattedComment"> One small nit: "git checkout &lt;path&gt;" will trash all changes that are not in the index (AKA staging area). I use it all the time to trash only select changes: "git add -p" and then "git checkout ." usually followed by "git reset". It's very powerful. But you need to have total situational awareness of your working copy for this to work without surprises.<br> </div> Tue, 06 Nov 2018 15:55:03 +0000 Hmm … https://lwn.net/Articles/770816/ https://lwn.net/Articles/770816/ smurf <div class="FormattedComment"> IMHO a group marker shouldn't mark the "previous N commits" to be a group (that won't work if one of these is itself a merge to something "outside" the group) – instead, it should declare a specific ancestor to be the one that's displayed when the group is collapsed.<br> <p> That special-ness could be even signalled without touching the core data structure: a normal no-follow merge commit mentions its parents in a specific order (the "null" parent is first). A "this is a group" commit would simply invert that.<br> </div> Tue, 06 Nov 2018 13:45:25 +0000 Hmm … https://lwn.net/Articles/770814/ https://lwn.net/Articles/770814/ epa <div class="FormattedComment"> I suspect that no new low-level machinery would be needed; instead a special type of commit declares the previous N commits (with the given SHAs) to have been part of a group, with a certain log message. 'git bisect' could become aware of groups (bisecting at top-level granularity first, then optionally breaking down to the next level to find the particular sub-commit, and so on) and 'git rebase -i' would need to show them somehow, and do something reasonable when you want to rewrite history changing the contents of a group. Then web interfaces like Github would let you review the grouped commit with an ability to click through to see the sub-commits it contains.<br> <p> Perhaps all this could be done with tags, I'm not sure -- but I like the idea that groups are immutable once created (just like ordinary commits), yet at the same time you can push a new group-declaring commit retrospectively making some previous commits part of your group. (I think it might be wise to forbid group spaghetti where a commit can be part of two overlapping groups, except for the straightforward case of nesting. That is something a git hook could take care of. The git machinery itself doesn't really get affected by that, however.)<br> </div> Tue, 06 Nov 2018 12:00:19 +0000 Hmm … https://lwn.net/Articles/770807/ https://lwn.net/Articles/770807/ epa <div class="FormattedComment"> Yes, as I mentioned you can get some of the benefits by merging a branch in one commit. But that forces a nonlinear history, while allowing nested changes would still give a linear timeline for bisecting, etc. <br> <p> Also it only really gives one level of nesting and is a bit clunky. Take for example the problem mentioned in an earlier post. To rename a file you may first do ‘git mv’ in one commit then change the contents in the next. Does anyone really land a separate branch just for that? What I envisage is something like ‘git group open; git commit; ...; git group close’. On closing the group you are prompted for a top-level commit message. Or you could group commits when rebasing. This would be similar to the current support for squashing commits into one, but still allowing the individual changes to be retrieved if you choose to ‘look inside’. <br> </div> Tue, 06 Nov 2018 07:08:30 +0000 Hmm … https://lwn.net/Articles/770806/ https://lwn.net/Articles/770806/ smurf <div class="FormattedComment"> Grouping commits is reasonably simple – you create a branch for them, and then do a non-fast-forward merge to the parent.<br> </div> Tue, 06 Nov 2018 06:28:29 +0000 Hmm … https://lwn.net/Articles/770797/ https://lwn.net/Articles/770797/ neilbrown <div class="FormattedComment"> In what way is it "clunky by comparison"?<br> Would it require changes in the git engine to achieve what you want, or would it be sufficient to add some commit-group-aware interfaces?<br> <p> </div> Tue, 06 Nov 2018 03:06:11 +0000 Hmm … https://lwn.net/Articles/770761/ https://lwn.net/Articles/770761/ epa <div class="FormattedComment"> I often miss the ability to group commits in git -- so one top-level commit could be unpacked into smaller ones if you choose to view it that way (and those smaller ones themselves could be nested commits, etc).<br> <p> That would take care of the 'doing this commit just so git doesn't become confused' problem and it would also help with patch sets and work on a particular feature -- where the whole work is merged as a single logical commit, but by bumping up the default nesting level you can drill down to the component changes. You can emulate this a little bit with branching and merging (where there is a single commit merging the feature branch) but it's clunky by comparison.<br> </div> Mon, 05 Nov 2018 19:47:50 +0000 Hmm … https://lwn.net/Articles/770757/ https://lwn.net/Articles/770757/ johill <div class="FormattedComment"> <font class="QuotedText">&gt; Svn operates in terms of tree snapshots while git operates in terms of changesets.</font><br> <p> Hm. I think that came out wrong?<br> <p> git doesn't really care about the changes at all, each commit just records the current state of the tree and the parent commit.<br> <p> Perhaps you meant to say something else?<br> <p> (FWIW, I've (ab?)used this property of git to great effect in some projects, e.g. tracking an automatically modified version of one tree in another, where you just have to provide a tree-&gt;tree mapping "function", and then git will sort out everything else basically by itself)<br> </div> Mon, 05 Nov 2018 18:47:07 +0000 Hmm … https://lwn.net/Articles/770754/ https://lwn.net/Articles/770754/ ms-tg <div class="FormattedComment"> Yes, I was just about to type the same reply. The git mv heuristic's most inconvenient failure case is the one you mentioned -- when renaming a source file also implies that you must change the naming inside the files. Considering how very common this really is across widely used programming languages, I'm also surprised that this is still an issue today.<br> <p> Instead of doing what seems semantically correct, we instead must:<br> 1. Locally git commit nothing more than the 'git mv OLDNAME NEW NAME'<br> 2. Locally git commit the naming change inside the file and all referring files<br> <p> And note in the commit history that commit (1) doesn't actually work, but is kept separate so that git can identify the rename in the history.<br> <p> Does anyone have a better standard practice for the above today?<br> </div> Mon, 05 Nov 2018 17:33:58 +0000 Hmm … https://lwn.net/Articles/770690/ https://lwn.net/Articles/770690/ NAR <div class="FormattedComment"> For some languages the filename and the "module/class name" in the file must be the same, otherwise the code doesn't even compile. Only renaming a file, but not changing it leads to broken build - so if we want all commits to be able to be built, the file has to be modified at the same time as it's being renamed and sometimes git doesn't notice that it's a file rename :-(<br> </div> Mon, 05 Nov 2018 13:53:28 +0000 Hmm … https://lwn.net/Articles/770679/ https://lwn.net/Articles/770679/ anselm <blockquote><em>An svn commit is actually better at "completely and unambiguously describ[ing] one particular state of your work (and its history)" than a git commit, because it encompasses all the repo's branches, not just the branch(es) the commit belongs to.</em></blockquote> <p> That depends on your philosophy. Svn operates in terms of tree snapshots while git operates in terms of changesets. With git, it is straightforward to see which sequence of changesets has resulted in the current state (“branch”), and it could be argued that the exact state and provenance of other branches actually isn't that important at that point. Svn gives you the “big picture” and of course that may also have its advantages every so often. OTOH, in git, a “branch” is a much more lightweight object than in svn, and that encourages the use of single-feature branches where you end up with a whole lot of them. </p> <p> Git also makes it easier to transplant changesets from one branch to another after the fact, or to publish or consume them remotely, and that of course is at the root of the whole “decentralised” thing that svn doesn't really address at all. Working with git, I find myself doing rebases and fixups quite a lot just to keep the development history of my code nice and logical, and unless svn has improved considerably in that area since I used it I have no idea at all how I would do that with svn. </p> Mon, 05 Nov 2018 12:29:30 +0000 Hmm … https://lwn.net/Articles/770665/ https://lwn.net/Articles/770665/ farnz <p>Sure, people don't normally work that way - but in special cases, you can do that if you have to. <p>And I'm surprised that you think that ordinary customers on the phone have the test suites, a full ancestry tree and the ability to query that tree. That's not my experience anywhere - and in the sort of place where you fix all branches at once, you probably also have customers with special case branches with a per-customer fix on it. In that case, a BUGS_FIXED file isn't helpful - it'll cover all the cases you've thought about, but not the special cases. <p>Also, this isn't about whether or not this is good practice (small shops do all sorts of things that aren't good practice!) - it's whether or not there's anything that git can't do that SVN can. This is something that SVN can do, partly by virtue of not being as complete a VCS, that git can't do. Mon, 05 Nov 2018 08:18:32 +0000 Hmm … https://lwn.net/Articles/770662/ https://lwn.net/Articles/770662/ epa <div class="FormattedComment"> No, what I mean is when you 'rm' a file or two in the working copy and then you want to restore those files from the current commit (or from git's index, if they happen to be in there).<br> <p> 'git checkout .' will appear to work for this task but it is highly dangerous, since it unconditionally trashes any other local changes. As another poster noted, there doesn't seem to be a command which does it, short of running 'git status', looking for 'deleted' lines, and running 'git checkout' over those.<br> <p> Now, you may say that this isn't a sensible way to work, and the right way to revert changes in a file if you messed it up is to run 'git checkout FILE' directly. Not to just delete the file and then hunt for the right incantation to bring it back. But rightly or wrongly it is a natural human reaction to say "I really messed this up, let's just delete it and start again".<br> <p> I did raise the feature request on the mailing list: <a href="https://public-inbox.org/git/loom.20150603T104534-909@post.gmane.org/">https://public-inbox.org/git/loom.20150603T104534-909@pos...</a><br> <p> </div> Mon, 05 Nov 2018 06:59:18 +0000 Hmm … https://lwn.net/Articles/770648/ https://lwn.net/Articles/770648/ smurf <div class="FormattedComment"> Sure I can check out everything at once. But (a) people usually don't work that way, (b) that also means that I can break everything at once. Guess what I, wearing my management hat, don't want to enable people to do – there's a reason we now have CI systems that run mandatory test suites before allowing anybody to check their "bug fix" into the release or CD branch.<br> <p> Yes, you need an ancestry tree (not a full one – just one that goes back to the parent of the bugfix) if you do this with git. Surprise: You are most likely to already have it. In any case, there are other ways; one no-brainer method is an entry in a BUGS_FIXED file you'd check. Another would be a test suite that actually verifies that the bug is (and stays) gone.<br> </div> Sun, 04 Nov 2018 20:36:11 +0000 Hmm … https://lwn.net/Articles/770652/ https://lwn.net/Articles/770652/ madscientist <div class="FormattedComment"> Note the OP includes a "." at the end of the git checkout command:<br> <p> <font class="QuotedText">&gt; It's more about 'git checkout .' which will silently overwrite every local change in the working copy.</font><br> <p> Adding a "." causes a checkout of all (modified) files from the current directory down. It cannot go to a different commit.<br> <p> For me, if I want to un-modify a file I use "git status" to see a list of modified files, and "git checkout filex filey ..." (perhaps copy/paste) to check out specific files. If I want to throw away everything I use "git reset --hard HEAD" or similar. I virtually never use "git checkout &lt;directory&gt;" and wouldn't suggest it to others, either.<br> <p> <font class="QuotedText">&gt; what is the safe git command to bring back deleted files</font><br> <p> By this I assume you mean a committed file that you have deleted and then want to recover and not an untracked file that you've deleted.<br> <p> The best way to know how to solve almost ANY issue in a workspace is to run "git status" and it will tell you how to undo it. For example, if you "rm somefile" and then decide you want it back, "git status" will tell you:<br> <p> <font class="QuotedText">&gt; Changes not staged for commit:</font><br> <font class="QuotedText">&gt; (use "git add/rm &lt;file&gt;..." to update what will be committed)</font><br> <font class="QuotedText">&gt; (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)</font><br> <p> <font class="QuotedText">&gt; deleted: Demo/readme.txt</font><br> <p> If you use "git rm somefile" then decide you want it back, "git status" will tell you:<br> <p> <font class="QuotedText">&gt; Changes to be committed:</font><br> <font class="QuotedText">&gt; (use "git reset HEAD &lt;file&gt;..." to unstage)</font><br> <p> <font class="QuotedText">&gt; deleted: Demo/readme.txt</font><br> <p> And finally when in doubt, I use "git stash" to stash modified files before doing any kind of bizarre operations on a repository where there are modifications I want to preserve, just in case.<br> </div> Sun, 04 Nov 2018 20:11:05 +0000 Hmm … https://lwn.net/Articles/770653/ https://lwn.net/Articles/770653/ mpr22 <div class="FormattedComment"> How often does the heuristic get it wrong if you don't make life impossible for it by making wholesale changes to the file in the same commit that you rename it?<br> </div> Sun, 04 Nov 2018 20:05:57 +0000 Hmm … https://lwn.net/Articles/770647/ https://lwn.net/Articles/770647/ smurf <div class="FormattedComment"> <font class="QuotedText">&gt; It's more about 'git checkout .' which will silently overwrite every local change in the working copy.</font><br> <p> That depends on whether you want to get a single file (or three), or go to a different commit. The latter refuses to overwrite things.<br> <p> <font class="QuotedText">&gt; what is the safe git command to bring back deleted files</font><br> <p> There is none. If you overwrite a file that hasn't been checked in, it's gone, just like when you use "rm". In fact, if you try to "git rm" a modified file, it'll warn you.<br> <p> Adding a warning option does make sense; I'll file a feature request.<br> <p> </div> Sun, 04 Nov 2018 19:03:52 +0000