0

When you do a git checkout some_branch, and your working directory is not clean, then Git will check if the checkout will result in any conflicts, and if so it will abort with:

$ git checkout some_branch
error: Your local changes to the following files would be overwritten by checkout:
        some_file
Please, commit your changes or stash them before you can switch branches.
Aborting

However, if the checkout will not result in any conflicts, then Git will switch to that new branch and carry over all uncommitted changes (and listing them, polite as Git is).

$ git checkout some_branch
M       some_file
M       some_other_file
Switched to branch 'some_branch'

So far so good ...

Now, not all Git users uses cmd line. If you use an IDE (like e.g. Eclipse) and do a checkout of some_branch with a dirty working directory which will not result in any conflicts, then you will not be nicely notified that the changes you were working on in previous_branch are still present in your working directory after changing to some_branch.

I.e. when you compile your code your uncommitted changes from previous_branch are still present in your working directory on some_branch.

Question #1:

Is it possible to force Git to abort a checkout if working directory is not clean (no matter if there are any conflicts or not)?

I would prefer a setting in global Git config.

Question #2:

If this is not possible to setup, is it then a valid request for a new config option in Git?

As I see it Git is very strong in context switching (i.e. working on multiple issues on multiple branches), and I could see a use for a setting which setup a strict check for if working directory is not clean (disregarding the check for conflicts).

This would mean that your changes created while on branch #1 will not be carried over when changing to branch #2, i.e. you will work strictly context based always.

Any views or opinions on this?

Jonas Bang Christensen
  • 1,041
  • 2
  • 10
  • 18

4 Answers4

2

I'm not aware of such an option, but here's a script to simulate this behavior. Maybe IDE(or OS) can be configured to run this script instead of git-checkout.

#!/bin/sh

MODIFIED=$(git status -s | grep ^\ M)

if [ "$MODIFIED" != "" ]; then
  echo "Current branch is dirty!"
  exit 1
else
  git checkout $1
fi

You can name this script git-cleancheckout, put to your $PATH and run like this

git cleancheckout mybranch
vrybas
  • 1,719
  • 17
  • 12
  • With some work I assume this could work. First, the script would have to take into account also Added, Deleted and Renamed files. Second, you would have to make your own version of the Eclipse EGit plugin to call `git-cleancheckout` instead of `git-checkout`. – Jonas Bang Christensen Mar 27 '14 at 08:25
0

There should be an option to "reset" the previous changes. It is depicted by --force on the command line. I use gitEx and this is available at the time of checkout <branch> as follows -

enter image description here

This would remove all your local changes automatically before checking out the branch. The option (stash) in the image can be used if you want to keep your changes in the store and get them back once you want to start working again on the old branch.

Nikhil Gupta
  • 1,708
  • 1
  • 23
  • 38
  • It's not the "reset" option I'm looking for, as I want to keep the uncommitted changes. Your proposal with GitEx (using "Stash") could be a workaround, but since we are using Eclipse and EGit I'm looking for a solution with EGit, or preferably in global Git config. – Jonas Bang Christensen Mar 26 '14 at 14:10
0

You should be able to use a post-checkout hook to do almost what you need. The limitation is that there is no pre-checkout hook, so you cannot abort. Instead, you can only discard local changes to get a clean state. If you want to, you can save the local changes with git stash save X and creating an archive of any untracked files before they are removed.

You indicate that you would prefer a setting in global git config; as previously suggested elsewhere on SO, with git 1.7.1 or later, you can use the following:

git config --global init.templatedir '~/.git-template'

to create all repositories (via git init or git clone) with templated hooks. The templated hooks are symbolic links that point into the repository itself, so they won't have any effect when you create other (unrelated) repositories:

mkdir -p ~/.git-template/hooks && \
  ln -sf ../../special-git-hooks/post-checkout ~/.git-template/hooks/.

The special-git-hooks/post-checkout script is the one that will implement the moral equivalent of git checkout --force:

#!/bin/sh
#
# git hook to clean branch checkout (git checkout --force plus more)
#

# arguments to post-checkout (see `man githooks`)
OLD_REV=$1
NEW_REV=$2
BRANCH=$3

if [ 0 = "$BRANCH" -o x"$OLD_REV" = x"$NEW_REV"]; then
    exit 0
fi

# Start from the repository root.
cd ./$(git rev-parse --show-cdup)

ARCHIVE=`mktemp -qu gitco-XXXXXXXXX`

git clean -nxd | sed 's/Would remove //' | cpio -oz --format ustar > $ARCHIVE.tgz
git add -f $ARCHIVE.tgz
git clean -fxd
git stash save $ARCHIVE

Note that this script doesn't handle files with newlines or other non-printing characters in their names. I'm working on a Perl version of this script that does.

Community
  • 1
  • 1
Alex Dupuy
  • 5,984
  • 3
  • 39
  • 35
0

In the commandline just checkout the previous branch if realize you forgot something. In EGit the changes are visible in the staging view, which unfortunately isn't always visible.

A new option in Git doesn't automatically find its way into Eclipse, but displaying a list of modified files after checkout seems like a reasable feature request for EGit.

robinr
  • 4,376
  • 2
  • 20
  • 18
  • Not sure I understand your 1st sentence, the case I'm making is not that you have forgotten something, but rather that you have gotten too much with you when changing branch. Your 2nd sentence, true, which is why I request ´checkout´ to abort. Your 3rd sentence, true, as EGit uses JGit it would not only require a new Git version, but also that JGit takes on that new Git version, however raising a request for EGit might be an idea I didn't think about (then I could ask them to implement proper ´amend´ also). – Jonas Bang Christensen Mar 29 '14 at 18:13