How to get abandoned changes back?

1,836 views
Skip to first unread message

Eric Tsai

unread,
Mar 17, 2009, 8:19:56 AM3/17/09
to Repo and Gerrit Discussion
Situation:
Change 3 depends on change 2, change 2 dependes on change 1.
I want changes 2 and 3 to be merged, but because change 1 has been
abandoned, so changes 2 and 3 are in "SUBMITTED" state.

What should I do to get change 1 back? I cannot find a way to get it
back in Gerrit UI. Or can I just ignore change 1, and forcing changes
2 and 3 to merge?

Thanks for answering.

Shawn Pearce

unread,
Mar 17, 2009, 10:13:27 AM3/17/09
to repo-d...@googlegroups.com
Change 1 should still exist under its change number (http://example.com/1) or its commit SHA-1 (http://example.com/r/hexsha1forcommit).  It should also show under the dependencies panel for change 2.  But yea, once abandoned, it can't be recovered from the web UI.

Since you want to submit 2,3 but not 1, you need to download 3 and rebase 2,3 on top of the current branch head, then upload replace them, so Gerrit gets new patch sets for the changes.

An outstanding feature request is to make this more automated in the web UI, especially if there are no conflicts, but I haven't had time to spend on it.

Eric Tsai

unread,
Mar 18, 2009, 9:03:56 AM3/18/09
to Repo and Gerrit Discussion
Sorry, I'm not quite familiar with git commands. Could you please show
me the correct command I should type?
I have only one master branch.

$ git pull ssh://xxx/yyy.git refs/changes/03/3/1
$ git rebase -i HEAD~2
$ git push ssh://xxx/yyy.git HEAD~2:refs/changes/2 HEAD~1:refs/changes/
3

Are these correct?

On Mar 17, 10:13 pm, Shawn Pearce <s...@google.com> wrote:

Shawn Pearce

unread,
Mar 18, 2009, 12:44:59 PM3/18/09
to repo-d...@googlegroups.com
On Wed, Mar 18, 2009 at 06:03, Eric Tsai <erict...@gmail.com> wrote:
>
> Sorry, I'm not quite familiar with git commands. Could you please show
> me the correct command I should type?
> I have only one master branch.
>
> $ git pull ssh://xxx/yyy.git refs/changes/03/3/1
> $ git rebase -i HEAD~2
> $ git push ssh://xxx/yyy.git HEAD~2:refs/changes/2 HEAD~1:refs/changes/3

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

Eric Tsai

unread,
Mar 19, 2009, 8:54:24 AM3/19/09
to Repo and Gerrit Discussion
Here is my local git log. The latest 3 changes show in Gerrit as
change 1, 2 & 3. The oldest change bypasses review.
=====================================================
commit c147550c18ba88846036f4e49bb3f48563ccb42c
Author: Eric Tsai <erictsai@localhost>
Date: Thu Mar 19 20:37:33 2009 +0800

add function: test3

commit 3975dfd2dc6d15b0ba423e96d9ec69de1f34048d
Author: Eric Tsai <erictsai@localhost>
Date: Thu Mar 19 20:37:23 2009 +0800

add function: test2

commit 42c06f59dee24b4af9e4e531738476d68d0e7489
Author: Eric Tsai <erictsai@localhost>
Date: Thu Mar 19 20:37:12 2009 +0800

add function: test1

commit b45a7543e6942415f798f7fd4e1c21831583a0db
Author: Eric Tsai <erictsai@localhost>
Date: Thu Mar 19 20:33:20 2009 +0800

add test.c
=====================================================


Change 1 has been abandoned by using Gerrit UI.
Then I run "git fetch", "git fetch ssh://xxx:29418/yyy.git refs/
changes/03/3/1" and "git checkout FETCH_HEAD".
I get:
=====================================================
Note: moving to "FETCH_HEAD" which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
git checkout -b <new_branch_name>
HEAD is now at c147550... add function: test3
=====================================================


When I do "git rebase --onto origin/master HEAD~2", I get:
=====================================================
First, rewinding head to replay your work on top of it...
HEAD is now at b45a754... add test.c
Applying add function: test2
error: patch failed: test.c:1
error: test.c: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merged test.c
CONFLICT (content): Merge conflict in test.c
Failed to merge in the changes.
Patch failed at 0001.

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --
skip".
To restore the original branch and stop rebasing run "git rebase --
abort".
=====================================================


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
=====================================================


So I run "git rebase --skip", then I get:
=====================================================
Applying add function: test3
error: patch failed: test.c:1
error: test.c: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merged test.c
CONFLICT (content): Merge conflict in test.c
Failed to merge in the changes.
Patch failed at 0002.

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --
skip".
To restore the original branch and stop rebasing run "git rebase --
abort".
=====================================================

I run "git rebase --skip" again, and get:
=====================================================
HEAD is now at b45a754... add test.c
Nothing to do.
=====================================================


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
=====================================================


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.
=====================================================


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'
=====================================================


What's the problem?


P.S.
$ git remote show origin
* remote origin
URL: http://localhost/yyy.git
Remote branch(es) merged with 'git pull' while on branch master
master
Tracked remote branches
master

On Mar 19, 12:44 am, Shawn Pearce <s...@google.com> wrote:

Shawn Pearce

unread,
Mar 19, 2009, 10:47:50 AM3/19/09
to repo-d...@googlegroups.com
On Thu, Mar 19, 2009 at 05:54, Eric Tsai <erict...@gmail.com> wrote:
>
> When I do "git rebase --onto origin/master HEAD~2", I get:
> =====================================================
> First, rewinding head to replay your work on top of it...
> HEAD is now at b45a754... add test.c
> Applying add function: test2
> error: patch failed: test.c:1
> error: test.c: patch does not apply
> Using index info to reconstruct a base tree...
> Falling back to patching base and 3-way merge...
> Auto-merged test.c
> CONFLICT (content): Merge conflict in test.c
> Failed to merge in the changes.
> Patch failed at 0001.
>
> When you have resolved this problem run "git rebase --continue".
> If you would prefer to skip this patch, instead run "git rebase --
> skip".
> To restore the original branch and stop rebasing run "git rebase --
> abort".
> =====================================================

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.

Eric Tsai

unread,
Mar 19, 2009, 2:22:42 PM3/19/09
to Repo and Gerrit Discussion
When git rebase stops, I do git diff to see there's problem in test.c.
So I edit test.c and do "git add test.c" then continue the rebase.
Now it works. Thank you so much!

I have another question: How do I undo a rebase?

Shawn Pearce

unread,
Mar 19, 2009, 3:11:19 PM3/19/09
to repo-d...@googlegroups.com
On Thu, Mar 19, 2009 at 11:22, Eric Tsai <erict...@gmail.com> wrote:
>
> I have another question: How do I undo a rebase?

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.

Eric Tsai

unread,
Mar 20, 2009, 1:15:05 PM3/20/09
to Repo and Gerrit Discussion
Hi Shawn,
I got a new problem.
Changes 2 and 3 are shown in Gerrit as MERGED. Running 'git log' on
the git server also shows changes 2 and 3.
But if I do 'git clone http://xxx/yyy.git', I didn't see changes 2 and
3 in downloaded test.c.
If I run 'git log' in folder yyy.git on the client, I don't see
changes 2 and 3.
I only see the change whitch bypasses review (add test.c).
I run gitk on the git server, I see the following text:
"Local changes checked in to index but not committed"
Is this the problem?

Shawn Pearce

unread,
Mar 20, 2009, 1:18:56 PM3/20/09
to repo-d...@googlegroups.com
Sounds to me like the changes were merged into a branch that isn't the
default branch. Look at "gitk --all" on the client, you should see
changes 2 and 3 in some other branch under the origin/ namespace.

Eric Tsai

unread,
Mar 21, 2009, 10:04:01 AM3/21/09
to Repo and Gerrit Discussion
'gitk --all' on the client: http://erictsai.tw/gitk--all_client.png
'gitk --all' on the server: http://erictsai.tw/gitk--all_server.png

After doing 'git push ssh://xxx/yyy.git HEAD~1:refs/changes/2
HEAD:refs/changes/3' and submitting patch set by Gerrit,
there seems to be an additional change (the green dot one) on the
server which removes all the content of test.c.
So if I git clone again, I get an empty test.c.

'git log' on both server and client is:
=====================================================
commit 8ff7d6d0b6c6eb1c2d150667b77b572780a52f27
Author: Eric Tsai <erict...@gmail.com>
Date: Sat Mar 21 21:46:56 2009 +0800

add function: test3

commit f6c00eb7e9f59f514a4a679fc8d17bf209b88d93
Author: Eric Tsai <erict...@gmail.com>
Date: Sat Mar 21 21:46:42 2009 +0800

add function: test2

commit 2efd179f046f3aa00fd49f8dcfa6de3f8dfa543a
Author: Eric Tsai <erict...@gmail.com>
Date: Sat Mar 21 21:45:17 2009 +0800

add test.c
=====================================================

On Mar 21, 1:18 am, Shawn Pearce <s...@google.com> wrote:
> Sounds to me like the changes were merged into a branch that isn't the
> default branch.  Look at "gitk --all" on the client, you should see
> changes 2 and 3 in some other branch under the origin/ namespace.
>
>
>
> On Fri, Mar 20, 2009 at 10:15, Eric Tsai <erictsa...@gmail.com> wrote:
>
> > Hi Shawn,
> > I got a new problem.
> > Changes 2 and 3 are shown in Gerrit as MERGED. Running 'git log' on
> > the git server also shows changes 2 and 3.
> > But if I do 'git clonehttp://xxx/yyy.git', I didn't see changes 2 and
> > 3 in downloaded test.c.
> > If I run 'git log' in folder yyy.git on the client, I don't see
> > changes 2 and 3.
> > I only see the change whitch bypasses review (add test.c).
> > I run gitk on the git server, I see the following text:
> > "Local changes checked in to index but not committed"
> > Is this the problem?
>
> > On Mar 20, 2:22 am, Eric Tsai <erictsa...@gmail.com> wrote:
> >> When git rebase stops, I do git diff to see there's problem in test.c.
> >> So I edit test.c and do "git add test.c" then continue the rebase.
> >> Now it works. Thank you so much!
>
> >> I have another question: How do I undo a rebase?- Hide quoted text -
>
> - Show quoted text -

Shawn Pearce

unread,
Mar 22, 2009, 7:39:40 PM3/22/09
to repo-d...@googlegroups.com
On Sat, Mar 21, 2009 at 07:04, Eric Tsai <erict...@gmail.com> wrote:
>
> 'gitk --all' on the client: http://erictsai.tw/gitk--all_client.png
> 'gitk --all' on the server: http://erictsai.tw/gitk--all_server.png
...

> there seems to be an additional change (the green dot one) on the
> server which removes all the content of test.c.

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.

Eric Tsai

unread,
Mar 23, 2009, 12:21:18 AM3/23/09
to Repo and Gerrit Discussion
On Mar 23, 7:39 am, Shawn Pearce <s...@google.com> wrote:
> 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.
>
I think I'm sure the server is using a bare repository.
Because if I run 'git commit' on the server, I'll get:
"fatal: This operation must be run in a work tree"
The .git directory and .git/index file only exist only on the client
but not on the server.


> 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.

Ya. After 'git clone', 'git log' only shows one record which bypasses
review (add test.c). And I get empty test.c.
If I didn't do 'git rebase --onto ......', I can get all merged
changes by 'git clone'.

Eric Tsai

unread,
Mar 23, 2009, 11:20:31 AM3/23/09
to Repo and Gerrit Discussion
I found that the problem is 'git update-server-info'.
I'm using http:// for git clone, but no for git push.
So I have to do 'git update-server-info' manually to update info/refs
everytime I sumit a patch.

On Mar 23, 12:21 pm, Eric Tsai <erictsa...@gmail.com> wrote:
> I think I'm sure the server is using a bare repository.
> Because if I run 'git commit' on the server, I'll get:
> "fatal: This operation must be run in a work tree"
> The .git directory and .git/index file only exist only on the client
> but not on the server.
>
>

Shawn Pearce

unread,
Mar 23, 2009, 12:46:32 PM3/23/09
to repo-d...@googlegroups.com
Oh, yea, uh, don't do that. :-)

Its possibly also a bug in Gerrit/JGit. JGit has the ability to
update the server info data, but it isn't enabled by default and
Gerrit doesn't enable it on its repositories. Its somewhat costly to
enable to rebuild the list of packs and refs on every modification,
but if you only have HTTP available then maybe it should be supported.

But really, HTTP is a horrible protocol for fetch/clone. It doesn't
provide any real delta transfer, and instead has to copy whole pack
files, which causes a lot of redundant data to be sent to the client.

Using ssh://server:29418/ is probably going to be much better for you
if you can't run any other server.

Mike

unread,
Mar 25, 2009, 11:46:23 AM3/25/09
to Repo and Gerrit Discussion
I'm in the same situation... we committed close to 300 changes on top
of a test commit, which was abandoned. Is there a way I can un-
abandon a change through the database (and flush caches)?

I'm not entirely clear on how Gerrit stores changes and I should
probably do some reading to figure that out.

Thanks,
Mike

On Mar 17, 7:13 am, Shawn Pearce <s...@google.com> wrote:

Shawn Pearce

unread,
Mar 25, 2009, 1:04:40 PM3/25/09
to repo-d...@googlegroups.com
On Wed, Mar 25, 2009 at 08:46, Mike <msw...@gmail.com> wrote:
>
> I'm in the same situation... we committed close to 300 changes on top
> of a test commit, which was abandoned.  Is there a way I can un-
> abandon a change through the database (and flush caches)?

So what, the test commit was actually submitted?

If you know its change number, you can switch it to submitted state instead:

UPDATE changes SET status = 'S' WHERE change_id = NNN;

That's it. There aren't any caches on this data to worry about. I
haven't identified it as worth caching yet.

Mike

unread,
Mar 26, 2009, 11:59:41 AM3/26/09
to Repo and Gerrit Discussion
Yeah, I figured we could just submit the test change, then manually
revert it later if it's anything more than a minor change (like adding
the word "test" to a readme file).

Glad it's as simple as changing the status in the database.

Mike


On Mar 25, 10:04 am, Shawn Pearce <s...@google.com> wrote:
Reply all
Reply to author
Forward
0 new messages