So it looks like you want two things:
Some commits should be kept confidential (for example, on a local branch) and never push or merge when you pull; they must remain "after" the general commits.
It should be mostly transparent to you; you want to work with the wizard, and the local branch is supported automatically. You simply decide which commits should be local, and the commands that interact with the remote repositories will ignore them.
So you want to write a script (name it git-something and put it in your path to add an additional git command) to identify and eliminate these commits. You will need a trigger for the script to recognize local commits. An easy way to do this is to put the magic word in the commit description - one that you will never use in real / shared commit - for recognizing a script. (If this sounds too loud for you, you can also use a special file in the commit tree, for example .THIS_COMMIT_IS_LOCAL_ONLY ; I did not do this in the examples, because it is a little more complicated.)
You will need a command to make a local commit from the current index / workdir; it's simple, it just calls git commit $@ -m "__LOCAL_COMMIT_ONLY__" (this is an example: the point is that it is doing something to mark that the commit is being created as local, and then canceled git commit). You will also need a command to temporarily display all local commits, execute another git command (pull, push, fetch, merge, whatever), and then reapply local commits. You will also use this command to create local commits that you intend to use, so that they always appear "under" locally only in your history.
Here is one example script that gives you both in one:
#!/bin/sh if [[ $1 eq 'new' ]]; then shift exec git commit $@ -m "__LOCAL_COMMIT_ONLY__" elif [[ $1 eq OLD_HEAD=$(git rev-parse HEAD) OLD_REAL_HEAD="$(git rev-list --grep=__LOCAL_COMMIT_ONLY__ | tail -n1)^" git reset --soft $OLD_REAL_HEAD git $@ git rebase --onto HEAD $OLD_REAL_HEAD $OLD_HEAD
Now, assuming you are calling the git-local script, use git local new to create a new local commit from the index (or git local new -a to create from the modified files in workdir), git local commit (the name is imperfect, sad) so that create a new "real" commit, git local push push, git local pull to pull, etc.
The main disadvantage of this is that it requires you to remember that most commands now have a prefix with local . If you forget to do this once, you will be a little excited, but not so bad - a quick git rebase -i will allow you to easily move your local commits back to the beginning, and you will start and run again. The biggest risk is that you accidentally use git push instead of git local push and git local push all your personal changes upstream, which will annoy everyone. To do this, you may need to write a small shell script to call instead of git itself (name it ~/bin/git and make sure ~/bin is in your path):
#!/bin/bash if [[ $1 eq 'push' ]]; then if git rev-list --grep=__LOCAL_COMMIT_ONLY__ | grep -q .; then echo "Can't push with local changes still active!" echo "Try using `git local push' instead." exit 1 fi fi exec /usr/bin/git "$@"
You can also do a pre-receive hook on a server that automatically rejects any message containing __LOCAL_COMMIT_ONLY__ in its message.