2

What I'm trying to accomplish is similar to what's in this question/answer: Viewing Unpushed Git Commits. I want to find out if there's anything in my local computer something that's not 'backed-up' in the gerrit server.

When trying to use the suggestions in that question is that when using Gerrit the results also lists commits that fall under the category of published commits that haven't been accepted to repo. They are shown with published/BRANCH_NAME marker in gitk. I only want to show commits that haven't been pushed to the remote gerrit repository even if they weren't accepted.

For example, if I use git log --graph --branches --not --remotes --decorate among the commits I get

commit 51blahblah123...456blah42e3 (refs/published/blah_fix, blah_fix)
Author: xyz <...>
Date:   Wed Jul 22 12:28:39 2012 -0500

  Commit description

  Change-Id: I83ae...blah...184

Those are the kinds of commits I'd like to skip. In gitk the last published commit shows with a purple background instead of the green background on branch names. Is there an equivalent of --remotes for those?

I tried also using git log origin/master..HEAD but I got the following error:

 fatal: ambiguous argument 'origin/master..HEAD': unknown revision or path not in the working tree.

So instead I tried using a specific revision (I think I am using a work branch instead of the remote's master branch) and it worked but that kidna defeats the purpose since I'd have to go look for all the branches.

I also considered git log @{u}.. --graph --decorate but that seems to skip the branches that I failed to create (by mistake) with remote tracking.

Community
  • 1
  • 1
frozenkoi
  • 3,228
  • 22
  • 33

2 Answers2

1

This command will list all commits that are reachable from your local branches, but are not present on your remote (assuming your remote is called origin):

git ls-remote origin | cut -f 1 | xargs git log --graph --decorate --branches --not
Chronial
  • 66,706
  • 14
  • 93
  • 99
  • Sadly it didn't help. The problem is that things like `refs/published/blah_branch` don't show up in the list of `git for-each-ref`. – frozenkoi Dec 17 '12 at 22:59
  • that’s not true. `for-each-ref` definitely lists everything - I just checked. The command I gave you won’t list `refs/published…/`, because that’s not what you wanted – stuff in `refs/published` is not on any remote. – Chronial Dec 18 '12 at 09:32
  • I must have my naming wrong. I'll try to better explain. When pushing to gerrit, changes need to be aproved before being included with the rest of the repository. At this point it shows as `published` I believe and the change is in the gerrit server. This is good enough for me (even if not accepted) and would like them being not listed. – frozenkoi Dec 18 '12 at 21:57
  • Sry, you are right. The correct command is not `for-each-ref`, but `ls-remote`. I corrected my answer – now it should definitely work. – Chronial Dec 19 '12 at 00:23
  • I think the problem is that I don't know what to call `refs/published/blah` since I don't think it's a tag name or branch tip. Thanks for the update. – frozenkoi Dec 19 '12 at 00:33
  • Also, does `ls-remote` require an available net connection to the server? – frozenkoi Dec 19 '12 at 00:40
  • yes, you need to be connected to the server to this. Git only stores the proper branches from the remote by default. If that’s a problem, you can also edit your `.git/config` file and look for `fetch = +refs/heads/*:refs/remotes/origin/*`. Adding ` +refs/*:refs/remote-all/origin/*` to that line should make `git fetch` also fetch the non-branch refs. Then `for-each-ref` will indeed list everything and you can use that again. But is the command I gave you working? – Chronial Dec 19 '12 at 00:53
  • Our gerrit server changed ip address, so I think it'll take longer to update my settings than I want you spending time with me on this. Thanks for the help thus far tho. – frozenkoi Dec 19 '12 at 01:57
0

In order to see if a commit has been pushed to remote repository (Gerrit’s changesets are recorded in the repository, so they will be present in git ls-remote output as Chronial mentioned), you can grep your local commits from the output.

Assuming your Gerrit repository is as origin remote:

With git ls-remote --quiet you can get a list of all remote references and with git log --pretty="%H" origin/master..master you can get commit hashes of commits that have not been merged to the repository yet.

So following Fish shell code would give you changes that are present in the repository:

for i in (git log --pretty="%H" origin/master..master)
    git ls-remote --quiet | grep $i
end

If the git ls-remote returns a row, then the commit has been pushed, otherwise it won’t be. Then just adjust this flow to your environment as necessary :)

For performance, you may want to save output of git ls-remote to a variable and check from there instead of always fetching the remote data all again.

In case you can use Gerrit’s SSH API, you can use

ssh -p 29418 -l GERRIT_USER GERRIT_SERVER gerrit query --format=json 7b5a1d510

instead of git ls-remote to get JSON response of details, where rowCount would tell amount of matches.

Smar
  • 8,109
  • 3
  • 36
  • 48