Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
checkout $tree: do not throw away unchanged index entries
When we "git checkout $tree", we pull paths from $tree into the index, and then check the resulting entries out to the worktree. Our method for the first step is rather heavy-handed, though; it clobbers the entire existing index entry, even if the content is the same. This means we lose our stat information, leading checkout_entry to later rewrite the entire file with identical content. Instead, let's see if we have the identical entry already in the index, in which case we leave it in place. That lets checkout_entry do the right thing. Our tests cover two interesting cases: 1. We make sure that a file which has no changes is not rewritten. 2. We make sure that we do update a file that is unchanged in the index (versus $tree), but has working tree changes. We keep the old index entry, and checkout_entry is able to realize that our stat information is out of date. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
- Loading branch information
c5326bd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is not working if you do a git checkout beetwen two branches (and one branch is merged into another), so all files do get a new timestamp
c5326bd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@peff Confirmed. I'm new to git and I ran into the same problem quickly.
Switching back & forth between two branches which are completely in sync touches a lot of files. Not all of them, but a lot. Which means I have to wait a couple of minutes for pointless rebuilds in Visual Studio, even though nothing has changed. Might be some weird interaction between git and VS2013 though, who knows...
c5326bd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@peff @gitster Having just re-read your commit comment for this issue, I'm pretty sure it doesn't solve the issue it was meant to solve ('do not touch files that are already up-to-date').
Our company policy requires me to create new feature branches for every issue I work on. So naturally, I switch between branches several times per day. And each time I do so, hundreds of files are touched without any actual changes! A full rebuild of our solution takes about 12 minutes. Everytime I switch branches, I have to wait for about 5 to 7 minutes for the forced rebuild which changes nothing. This is defeating the whole purpose of being able to "quickly" switch branches in the same working tree. It's beginning to take its toll on me and I'm considering to create separate working trees for every feature branch I create. Any interest in fixing or at least investigating this?
c5326bd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ZwergNaseXXL Do you mind taking this to the git mailing list? That's where development is discussed. Info is at https://git-scm.com/community
c5326bd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the description in the commit message wrong? I think update_some() called here is about "git checkout $tree $path1 $path2 ..." (i.e. grabbing some paths out of tree-ish), not "git checkout $commit" (i.e. branch switching). I think that is what makes mkress and ZwergNaseXXL confused.
I think branch switching already has "preserve timestamps etc." logic for paths that do not change.
$ ls -l COPYING
-rw-r----- 1 jch eng 18765 May 11 14:35 COPYING
$ git checkout next
Switched to branch 'next'
$ ls -l COPYING
-rw-r----- 1 jch eng 18765 May 11 14:35 COPYING
$ git checkout master
Switched to branch 'master'
$ ls -l COPYING
-rw-r----- 1 jch eng 18765 May 11 14:35 COPYING
$ date
Fri May 13 15:52:13 PDT 2016
As we can see, with two branches that do not change a path,
switching between them do not change the timestamp of the
path (for obvious reasons).
c5326bd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the commit message said
$tree
to indicate that, but it really should have beencheckout $tree .
or similar.I agree that branch-switching is not related, and also that it already handles this properly.
c5326bd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a workaround i use another index-file for every branch - so the checkout is also correct, when switching between branches.
`#!/bin/sh
worktree=path/to/checkout/directory
branch=$(echo "$1" | cut -d/ -f3);
checkout files to worktree
GIT_INDEX_FILE=/path/to/git/direcotry/index-$branch git --work-tree="$worktree" checkout $branch -f
`