Uhm, more like:
# Make sure the upstream branch is current.
$ git fetch
# Get just the current on a detached head
$ git fetch refs/changes/03/3/1
$ git checkout FETCH_HEAD
# Rebase the last two commits onto the upstream
$ git rebase --onto origin/master HEAD~2
# Replace the last two commits on Gerrit:
$ git push ssh://xxx/yyy.git HEAD~1:refs/changes/2 HEAD:refs/changes/3
Oh. Here's why you need to do these sorts of things on your client,
and not on the Gerrit server.
Git can't automatically delete your abandoned change from the history.
When it tried to do it for you given the rebase command, it ran into
a file conflict. The two changes (change 1 and change 2) modified
sections of the file that are too close together to be mangled by
machine. Git stops, and asks you to help it by editing the file by
hand to correct the problem.
> Then if I run "git rebase --continue", I'll get:
> =====================================================
> You must edit all merge conflicts and then
> mark them as resolved using git add
> =====================================================
You ignored Git.
> So I run "git rebase --skip", then I get:
and then continued to ignore it by saying "you know what, change 2 is
also pointless/unnecessary, discard it"...
> =====================================================
> Applying add function: test3
> error: patch failed: test.c:1
which conflicted again...
> I run "git rebase --skip" again, and get:
so yet again you say "change 3 is also pointless/unnecessary, discard it...'
> =====================================================
> HEAD is now at b45a754... add test.c
> Nothing to do.
> =====================================================
and Git says "oh, ok, then you really meant that very first commit,
aka origin/master, so I'll stay there"...
> After running these commands, currently the local git log is:
> =====================================================
> commit b45a7543e6942415f798f7fd4e1c21831583a0db
> Author: Eric Tsai <erictsai@localhost>
> Date: Thu Mar 19 20:33:20 2009 +0800
>
> add test.c
> =====================================================
and that is why all you see is that one very first commit.
> Then I run "git push ssh://xxx:29418/yyy.git HEAD~1:refs/changes/2
> HEAD:refs/changes/3"
> I get:
> =====================================================
> error: src refspec HEAD~1 does not match any.
> =====================================================
and that error means, there isn't a commit before HEAD. Yea, its an
obtuse error, but Git tried to look for the commit before the current
one (HEAD) and there isn't one, because that is where the history
stops.
> So I try ""git push ssh://xxx:29418/yyy.git 3975df:refs/changes/2
> c14755:refs/changes/3"
> I get:
> =====================================================
> Total 0 (delta 0), reused 0 (delta 0)
> To ssh://xxx:29418/yyy.git
> ! [remote rejected] 3975df -> refs/changes/2 (patch set exists)
> ! [remote rejected] c14755 -> refs/changes/3 (patch set exists)
> error: failed to push some refs to 'ssh://xxx:29418/yyy.git'
> =====================================================
Those two commits already are known to Gerrit. You didn't change anything.
Lots of ways.
git reset --hard branch@{1}
git reset --hard ORIG_HEAD
...
it depends. The ORIG_HEAD immediately after a rebase points to the
commit you had before the rebase started, but rebase, reset and pull
modify it, so its more-or-less only one "undo" step.
The branch@{n} syntax gives you access to the reflog, where n is how
many steps back (see e.g. "git log -g branch" or "git reflog show"),
giving you more steps of undo.
It seems that your server has a working directory, and an index. That
is incorrect. The server should be a bare git repository, as Gerrit
does not update the working directory when it makes changes. You are
seeing this difference on test.c because the test.c file exists in the
most recent commit on the master branch, but it doesn't exist in the
working directory, or in the associated $GIT_DIR/index file.
Make the server use a bare repository.
> So if I git clone again, I get an empty test.c.
Are you sure that is the behavior? The screen shots indicate the
deletion of test.c on the server is not committed, and thus wouldn't
clone to a client.