How to git pull latest changes from gerrit changeset + master

12,836 views
Skip to first unread message

Jeffery Fernandez

unread,
Feb 24, 2012, 7:57:23 PM2/24/12
to repo-d...@googlegroups.com
I have a workflow (attached screenshot) with my team where before any change is made to a local branch the Developer executes a "git pull". This pull gets any changes which have been merged into master since the last pull was made. 

As a QA lead, I sometimes fix some issues for the Developer. To do this, I fetch the latest patch of the changeset and modify the code locally and push the changes back to refs/for/master. This results in a new patch for the changeset with the committer being myself. 

The problem I am facing is when the Developer pulls the changes with "git pull" he will not get the latest patch I submitted, which is obvious because the git pull only gets the changes from master branch. How can I automate the pull so that it fetches the latest changes from master as well from the changeset branch?

Is there a wildcard syntax I can use e.g. 

git pull origin refs/changes/92/* 
and then 
git pull origin master
Git - Gerrit.png

Roland Schulz

unread,
Feb 24, 2012, 9:04:14 PM2/24/12
to Jeffery Fernandez, repo-d...@googlegroups.com
I don't think so. But you could easily write a script to do it by using:
ssh {host}:{port} gerrit query --current-patch-set {change} |grep ref 

But pull won't work unless you expect your developer not to have his earlier version of the change in his current local branch. If you expect your developer to have his earlier version of the change awith potential local changes in the workspace and/or index (but not yet amended to the change) you could do:
git stash
git fetch origin refs/changes/92/{patch-id-from-script}
git reset --hard FETCH_HEAD  #or: git checkout FETCH_HEAD
git stash pop

Roland


git pull origin refs/changes/92/* 
and then 
git pull origin master



--
ORNL/UT Center for Molecular Biophysics cmb.ornl.gov
865-241-1537, ORNL PO BOX 2008 MS6309

Jason Axelson

unread,
Feb 24, 2012, 9:09:40 PM2/24/12
to Roland Schulz, Jeffery Fernandez, repo-d...@googlegroups.com
On Fri, Feb 24, 2012 at 4:04 PM, Roland Schulz <rol...@utk.edu> wrote:
> I don't think so. But you could easily write a script to do it by using:
> ssh {host}:{port} gerrit query --current-patch-set {change} |grep ref

I think that this functionality might be useful in one of the gerrit
helper scripts like repo or git-review:

https://github.com/openstack-ci/git-review

I know this is something that I would find valuable. And it would be
especially useful if reviewers are ever able to edit changes through
the web interface (to do things like fix minor typos).

Maybe you could replace git fetch to warn you if any of your commits
are outdated by fetching all the changesets and comparing where the
newest version of the change is.

Jason

Magnus Bäck

unread,
Feb 24, 2012, 9:13:26 PM2/24/12
to repo-d...@googlegroups.com
On Friday, February 24, 2012 at 19:57 EST,
Jeffery Fernandez <jefferyf...@gmail.com> wrote:

> I have a workflow (attached screenshot) with my team where before any
> change is made to a local branch the Developer executes a "git pull".
> This pull gets any changes which have been merged into master since
> the last pull was made.

I was just about to bark about using "git pull --rebase" instead of a
plain "git pull", but according to the workflow diagram you're already
doing that. Good.

> As a QA lead, I sometimes fix some issues for the Developer. To do
> this, I fetch the latest patch of the changeset and modify the code
> locally and push the changes back to refs/for/master. This results in
> a new patch for the changeset with the committer being myself.
>
> The problem I am facing is when the Developer pulls the changes with
> "git pull" he will not get the latest patch I submitted, which is
> obvious because the git pull only gets the changes from master branch.
> How can I automate the pull so that it fetches the latest changes from
> master as well from the changeset branch?
>
> Is there a wildcard syntax I can use e.g.
>
> git pull origin refs/changes/92/*
> and then
> git pull origin master

Well, Git's fetch refspecs can contain wildcards so I guess you
could fetch refs/changes/x/* (where x is the change number mod 100)
and find the patch set you're looking for by examining FETCH_HEAD.

But I'd rather suggest you use the "query" SSH command for this
(see http://goo.gl/0KzVm). Use the --current-patch-set option and
select JSON output. It shouldn't take many lines of e.g. Python
to produce the refspec that needs to be pulled (I believe the
refspec of each patch set is in a field of its own).

Or, the developer will just have to look up the refspec to pull
from via the Gerrit web UI.

--
Magnus Bäck
ba...@google.com

Jeffery Fernandez

unread,
Feb 26, 2012, 4:53:45 AM2/26/12
to repo-d...@googlegroups.com
Using the gerrit query command, I am able to get the list of refs/patches on the remote:

refs/changes/92/292/1
refs/changes/92/292/2
refs/changes/92/292/3
refs/changes/92/292/4
refs/changes/92/292/5
refs/changes/92/292/6
refs/changes/92/292/7
refs/changes/92/292/8
refs/changes/92/292/9
refs/changes/92/292/10
refs/changes/92/292/11
refs/changes/92/292/12
refs/changes/92/292/13

How can I verify those refs are available in the HEAD of the local branch I am in?



--
ORNL/UT Center for Molecular Biophysics cmb.ornl.gov
865-241-1537, ORNL PO BOX 2008 MS6309

Jeffery Fernandez

unread,
Feb 26, 2012, 5:16:43 AM2/26/12
to repo-d...@googlegroups.com, Jeffery Fernandez
here is my attempt of syncing all refs of the changeset:

#!/bin/sh

# Extract the Change Id from HEAD
CHANGE_ID=$(git show HEAD --summary | grep "Change-Id:" | awk -F ' ' '{print $2}')
if [ "${CHANGE_ID}" != "" ]; then

    # Get the Gerrit changeset number
    CHANGESET_NUMBER=$(ssh source-code gerrit query "${CHANGE_ID}" | grep "number:" | awk -F ' ' '{print $2}')

    # Get the Changeset Refs
    CHANGESET_REFS=$(ssh source-code gerrit query --patch-sets "${CHANGESET_NUMBER}" | grep "ref:" | awk -F ' ' '{print $2}')

    # Fetch all the refs from Remote
    for ref in "${CHANGESET_REFS}"; do git fetch origin $ref && git reset --hard FETCH_HEAD; done;
fi

On Saturday, 25 February 2012 13:04:14 UTC+11, Roland Schulz wrote:

Magnus Bäck

unread,
Feb 27, 2012, 10:51:31 AM2/27/12
to repo-d...@googlegroups.com
On Sunday, February 26, 2012 at 04:53 EST,
Jeffery Fernandez <jefferyf...@gmail.com> wrote:

> Using the gerrit query command, I am able to get the list of
> refs/patches on the remote:
>
> refs/changes/92/292/1
> refs/changes/92/292/2
> refs/changes/92/292/3
> refs/changes/92/292/4
> refs/changes/92/292/5
> refs/changes/92/292/6
> refs/changes/92/292/7
> refs/changes/92/292/8
> refs/changes/92/292/9
> refs/changes/92/292/10
> refs/changes/92/292/11
> refs/changes/92/292/12
> refs/changes/92/292/13
>
> How can I verify those refs are available in the HEAD of the local
> branch I am in?

I assume you mean that you want to check that *one* of these commits
is reachable from HEAD, not that *all* are reachable from HEAD since
that will never be the case. You can use "git log" or "git rev-list"
to test reachability:

if [ $(git rev-list HEAD..<patch> | wc -l) -eq 0 ] ; then
echo "Patch reachable from HEAD"
fi

Don't forget that this will only work as long as you don't rebase
your topic branch.

--
Magnus Bäck
ba...@google.com

Magnus Bäck

unread,
Feb 27, 2012, 11:05:07 AM2/27/12
to repo-d...@googlegroups.com
On Sunday, February 26, 2012 at 05:16 EST,
Jeffery Fernandez <jefferyf...@gmail.com> wrote:

> here is my attempt of syncing all refs of the changeset:
>
> #!/bin/sh
>
> # Extract the Change Id from HEAD
> CHANGE_ID=$(git show HEAD --summary | grep "Change-Id:" | awk -F ' '
> '{print $2}')

If HEAD is a commit that has been uploaded (I don't really understand
what you're trying to do so I can't judge whether this will be the case)
you can use the fact that the query command accepts a SHA-1 as input:

SHA1=$(git rev-parse HEAD)

Then, pass $SHA1 as the query.

> if [ "${CHANGE_ID}" != "" ]; then
>
> # Get the Gerrit changeset number
> CHANGESET_NUMBER=$(ssh source-code gerrit query "${CHANGE_ID}" |
> grep "number:" | awk -F ' ' '{print $2}')

The grep expression is fragile; you should make sure you only match
"number:" at the beginning of lines:

... | grep "^ *number: " | ...

> # Get the Changeset Refs
> CHANGESET_REFS=$(ssh source-code gerrit query --patch-sets
> "${CHANGESET_NUMBER}" | grep "ref:" | awk -F ' ' '{print $2}')
>
> # Fetch all the refs from Remote
> for ref in "${CHANGESET_REFS}"; do git fetch origin $ref && git
> reset --hard FETCH_HEAD; done;
> fi

While it won't make much of a difference in most cases, there's no need
to waste time on running "git reset" in each iteration of the loop.

--
Magnus Bäck
ba...@google.com

Jason Axelson

unread,
Feb 27, 2012, 2:02:40 PM2/27/12
to repo-d...@googlegroups.com
Here's a snippet of python code that checks if all the current commits
for your branch (currently hard-coded to origin/dev) are in gerrit.
Note that this checks the commits not the changes, so if you update a
change then this will say that the commit is not in gerrit. Also the
gerrit function is basically "ssh source-code gerrit".

err, pipe2 = os.popen2("git log --oneline --format='%H'
origin/dev..HEAD | awk '{print $1}'")
commits = [line.strip() for line in pipe2]
print commits
for x in commits:
print "x is %s" % x
inGerrit = gerrit("query %s|grep rowCount:|awk '{print $2}'" % x)
inGerrit = inGerrit.strip()
print "in gerrit is %s" % inGerrit
if inGerrit == "0":
print "is not in gerrit"
elif inGerrit == "1":
print "is in gerrit"
else:
print "ERROR in Gerrit is %s" % inGerrit


Jason

> --
> To unsubscribe, email repo-discuss...@googlegroups.com

Jeffery Fernandez

unread,
Feb 27, 2012, 11:24:59 PM2/27/12
to repo-d...@googlegroups.com
On Tuesday, 28 February 2012 03:05:07 UTC+11, Magnus Bäck wrote:
On Sunday, February 26, 2012 at 05:16 EST,
     Jeffery Fernandez <jefferyf...@gmail.com> wrote:

> here is my attempt of syncing all refs of the changeset:
>
> #!/bin/sh
>
> # Extract the Change Id from HEAD
> CHANGE_ID=$(git show HEAD --summary | grep "Change-Id:" | awk -F ' '
> '{print $2}')

If HEAD is a commit that has been uploaded (I don't really understand
what you're trying to do so I can't judge whether this will be the case)

Here I was checking to see if the  commit in HEAD has a change Id. But I guess I could just use the commit sha1 instead.
 

you can use the fact that the query command accepts a SHA-1 as input:

   SHA1=$(git rev-parse HEAD)

Then, pass $SHA1 as the query.

> if [ "${CHANGE_ID}" != "" ]; then
>
>     # Get the Gerrit changeset number
>     CHANGESET_NUMBER=$(ssh source-code gerrit query "${CHANGE_ID}" |
> grep "number:" | awk -F ' ' '{print $2}')

The grep expression is fragile; you should make sure you only match
"number:" at the beginning of lines:

yep, I have updated the script
 

   ... | grep "^ *number: " | ...

>     # Get the Changeset Refs
>     CHANGESET_REFS=$(ssh source-code gerrit query --patch-sets
> "${CHANGESET_NUMBER}" | grep "ref:" | awk -F ' ' '{print $2}')
>
>     # Fetch all the refs from Remote
>     for ref in "${CHANGESET_REFS}"; do git fetch origin $ref && git
> reset --hard FETCH_HEAD; done;
> fi

While it won't make much of a difference in most cases, there's no need
to waste time on running "git reset" in each iteration of the loop.

makes sense 


--
Magnus Bäck
ba...@google.com

Jeffery Fernandez

unread,
Feb 28, 2012, 6:12:10 AM2/28/12
to repo-d...@googlegroups.com
The topic branch gets rebased every time there are new changes in master, so I guess this won't work for me.
 

--
Magnus Bäck
ba...@google.com

Magnus Bäck

unread,
Dec 21, 2012, 3:26:10 PM12/21/12
to repo-d...@googlegroups.com
On Friday, December 21, 2012 at 15:04 EST,
Mohit Khanna <mr.mohi...@gmail.com> wrote:

> I am trying to right a similar bash script to fetch the recently
> uploaded changes from the gerrit server. Can you share the script
> that you wrote for the same..?
>
> ssh -p 29418 "sample-gerrit-server" gerrit query -commit-message
> --current-patch-set status:open project:"project name" branch:master
> is:reviewed label:CodeReview=1 |grep refs| awk -F ' ' {'print $2'}
>
> Using the command above I am getting all the open gerrits present at
> the server. I was wondering if there is a way to fetch only the most
> recent gerrits.

There was a thread about this earlier this week.

https://groups.google.com/d/topic/repo-discuss/rnGBkZ3yXuM/discussion

Since you're only interested in open changes, the original suggestion
in that thread to add "NOT age:1d" to the query should work fine. Note
that this doesn't give you the changes uploaded in the past day but
all changes that have been updated, which would be a superset of the
recently uploaded changes.

--
Magnus Bäck
ba...@google.com
Reply all
Reply to author
Forward
0 new messages