On Sat, 15 Jun 2013 14:37:59 +0200 Thorsten Jolitz <tjol...@googlemail.com> wrote:
> I messed up a commit message, and wanted to fix it immediatly after > the commit (but I already merged the commit into master and pushed > both - master and work branch - to github, unfortunately). > > Thus I ran > > ,------------------- > | git commit --amend > `------------------- [...] > To my surprise, a new commit hash was created, and the hash of the > original commit disappeared from the history. That is perfectly reasonable: the SHA-1 name of a commit is calculated not just over the data comprising the snapshot of the repository that commit references but rather over the commit object itself as well, and it contains your commit message as well as author, committer names and e-mails, commit date and other metadata. Obviously, the commit object always changes when you do `git amend` (at least because the commit date changes). > Then trying to push to orign at github, git tells me I can't push > because head in orign is behind local head -> pull first. You might consider to rightfully ignore this: Git assumes that if you're trying to push to a branch something which does not contain the tip of that branch in its history then this means someone managed to update that branch with their work and so you're supposed to reconcile that work with yours by means of merging (or rebasing), that's why it tells you to pull -- pulling means fetching and then merging. But since you know you've just re-written some history, you might as well consider force-pushing your work by doing git push --force github master work This should be first discussed with your fellow developers, if any, though: if they managed to fetch the current state of affected branches and base anything local on this state, your force-pushing will require them to rebase their local work on the updated state of the affected branches. Hence next time you should think hard about whether you really want to do commit amendment or other sorts of history rewriting if you've pushed your work already. Note that while history rewriting is a paramount property of Git, an essential rule of thumb is that only your purely local (unpublished, meaning unpushed to a public place) history is "volatile", and anything published should in most cases be considered more or less "cast in stone". > But when I try to pull I get: > > ,--------------------------------------------------------- > | $ git --no-pager pull -v > | Von github.com:my/repo > | = [aktuell] master -> origin/master > | = [aktuell] work -> origin/work > | Your configuration specifies to merge with the ref 'work > | from the remote, but no such ref was fetched. > | git exited abnormally with code 1. > `--------------------------------------------------------- > > So what to do? This error has nothing to do with the commit amendment you did. When you do `git pull` like you showed (that is, without any "refspecs" which tell Git what to get from the remote side), `git pull` goes like this: 1) Considers the branch.<your_checked_out_branch>.merge configuration variable to know which branch is "the upstream" for the local one, and considers the branch.<your_checked_out_branch>.remote configuration variable to know where that branch should be fetched from. 2) Fetches the objects of the indicated branch which are missing locally from the indicated remote repository, writes them to your local git repository and writes the SHA-1 name of its tip commit into the special "ref" named FETCH_HEAD. 3) Attempts to merge lines of history referenced to by the FETCH_HEAD ref into the currently checked out branch -- in your simple case this will be just a single line of history. For instance, for one of my local repositories, which has two branches, "master" and "uuid", both or which communicate with the same-named branches in a remote repository, "origin", I have: $ git config --local --list | grep "^branch" branch.master.remote=origin branch.master.merge=refs/heads/master branch.uuid.remote=origin branch.uuid.merge=refs/heads/uuid Now consider that unless you mistyped the error message, Git says it failed to fetch the ref named "'work" -- notice the leading single quote. My take on this is that your branch.work.merge configuration variable contains a bogus value. You could check this by inspecting the output of $ git config --local --list or just by reading the .git/config file. In either case, you should supposedly fix the setting. *BUT* note that as explained above, pulling in your particular case really has no sense: Git would attempt to merge what it fetched from the remote side (your original, "not yet amended" commit) with your amended commit. Hence in your case you really have two options: 1) Force-push your modified branches as explained above. 2) Decide not to mess with the situation and revert your *local* branch(es) to the state before the amendment. That would amount to resetting them to their pre-amendment state, for instance, if you amended your commit on the local branch "work", you could reset that branch back like this: $ git fetch # makes origin/work up-to-date, among other things $ git checkout work ... now verify everything is as expected: $ git log work $ git log origin/work ... if it's all right (origin/work and work differ just by their tip commits), proceed with resetting: $ git reset origin/work To get better idea about how `git reset` works, consider reading the excellent "Reset Demystified" document . > PS > Why is the gmane version of this list unidirectional? It would be much > more convenient to be able to use it as newsgroup too. We have nothing to do with this as we do not control neither GMANE nor Google Groups. 1. http://git-scm.com/blog/2011/07/11/reset.html -- You received this message because you are subscribed to the Google Groups "Git for human beings" group. To unsubscribe from this group and stop receiving emails from it, send an email to git-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.