88

Is it possible to view the reflog of a remote? That is, I want to know what the output of git reflog is on another remote machine.

Note that I am not asking for the reflog of remote-tracking branches (such as origin/master); I am asking for what reflog says on the other machine.

Guildenstern
  • 2,179
  • 1
  • 17
  • 39
Alexander Bird
  • 38,679
  • 42
  • 124
  • 159
  • 3
    If you have access to the file system of the remote system (which oftentimes is a bare repos) you always have the option of running git reflog there. But having such access is normally not possible. I have a habit of making this possible on git servers (using a read-only file share), just in order to to make it possible to review the reflog on the server side. – Anders Zommarin Jul 30 '14 at 11:51

4 Answers4

65

On the off chance that the remote machine is a github repository,

  1. First use Github’s Events API to retrieve the commit SHA.
    curl https://api.github.com/repos/<user>/<repo>/events

  2. Identify the SHA of the orphan commit-id that no longer exists in any branch.

  3. Next, use Github’s Refs API to create a new branch pointing to the orphan commit.

    curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d '{"ref":"refs/heads/D-commit", "sha":"<orphan-commit-id>"}' https://api.github.com/repos/<user>/<repo>/git/refs

    Replace <orphan-commit-id> in the above command with the SHA identified in step 2.

  4. Finally git fetch the newly created branch into your local repository.
    From there you can cherry-pick or merge the commit(s) back into your work.

Check out this article for an actual example.

TheCodeArtist
  • 21,479
  • 4
  • 69
  • 130
Błażej Czapp
  • 2,478
  • 2
  • 24
  • 18
  • 12
    Thanks a lot! For those less inclined to use the command line, you can also bypass step 3 by just open https://github.com///commits/ and create a new branch from it directly in the "Tree:" dropdown. Then just fetch it normally. – waldyrious Sep 15 '16 at 07:45
  • 4
    If you get a `"message": "Not Found"` error, this means you need to authenticate e.g. by passing an access_token query string. – Andy Hayden Mar 07 '17 at 06:39
  • 5
    For me the easiest way to track down the *SHA of the orphan commit-id* was to look at the last build on CircleCI (or [insert CI service here]). – samjewell Mar 24 '17 at 13:57
  • 2
    [Here](https://developer.github.com/v3/) are instructions for how you can authenticate. – mkasberg Aug 09 '18 at 15:42
  • 3
    This answer looks like it addresses a different problem than the question asks. It looks like it addresses how to recover a commit that's no longer reachable from any branch or tag, whereas the question asks how to view the reflog -- the history of what a branch or tag referred to. – Matt McClure Jun 25 '20 at 05:47
  • Very nice! Was able to find the event and identify the `before` commit hash. This is going to come very handy multiple times. – haridsv Jan 28 '21 at 18:32
  • Instead of _recovering_ the github commit, is there a way to remove it from github? – racitup Jun 09 '21 at 17:31
  • 1
    YOU ARE A GOD THANK YOU SO MUCH! – Ke Ke Sep 13 '21 at 22:50
  • @MattMcClure, absolutely, folks should stop upvoting this answer. – mlntdrv Jan 06 '22 at 10:59
  • 4
    To be clear, to future readers, you want to add `-u :` to the command in 3. – Daniel Porteous Mar 11 '22 at 03:46
  • 1
    @waldyrious this should now be `.../commit/...` (singular) and not "commits" (plural) – Yonatan May 31 '22 at 15:34
  • Also to list repository events use: `curl -H "Accept: application/vnd.github.v3+json" -H "Authorization: token " https://api.github.com/repos/OWNER/REPO/events` From: https://docs.github.com/en/rest/activity/events#list-repository-events – aderchox Jun 28 '22 at 17:32
  • "the commit id of the orphan".... and how are we supposed to figure out that when it could have been orphaned YEARS ago...it is likely to have been GC'ed.... – David V. Corbin Aug 24 '23 at 15:42
55

The answer is basically "no" (except on that machine), because the reflog is a log of locally-made re-assignments of some ref-name. Essentially, every time you run git update-ref -m msg <name> <target> the update is logged ... locally: .git/logs/<name> gets a line appended:

$ git update-ref -m foo HEAD HEAD^
$ tail -1 .git/logs/HEAD
2418b6ba8fd0289933c9351260a272b8e410867f 8d945134b0cead535d66af29c8eb4228b5dc3763 [redacted] <[redacted]> 1334106483 -0600     foo

(the thing before the message, in this case foo, is not spaces but rather a tab; I expanded it for SO purposes). Conceptually, everything else that moves a branch tip invokes git update-ref to do it (some are shell scripts and literally do that, others just invoke the C code that does all the file-updating) ... and everything in .git/logs makes up the reflog.

If there were things in the underlying git:// and/or ssh:// protocols that let you get at the reflog, that would do it, but as far as I know there isn't.

torek
  • 448,244
  • 59
  • 642
  • 775
9

On GitHub, if you did by mistake a git push --force on master before to fetch the merged changes and in the meanwhile the merged branch was deleted (yeah, it happened to me), you can look for the merged pull request and go to the Commits section, e.g:

enter image description here

Then you go on the last commit and click on the <> button (that has title "Browse the repository at this point in the history").

This will bring you to the "deleted" point of history. From here you can:

  • create a new branch and then open a new pull request (recommended if the change comes from another repository).
  • open a new pull request (recommended for commits inside your repository).
JeanValjean
  • 17,172
  • 23
  • 113
  • 157
  • Another solution is to use `git push --force-with-lease` https://thoughtbot.com/blog/git-push-force-with-lease – Othmane El Kesri Oct 15 '19 at 16:23
  • 1
    For Gitlab users: you can copy the commit SHA ID of the last commit before the rebase, go to the project page, click on the "+" icon next to the repo name, click on "New branch" and paste the last commit ID. You can now checkout this new branch locally or create a MR. – Letik Mar 01 '22 at 17:01
-1

You can use this command to view remote reflogs:

git reflog refs/remotes/<remote name>/<branch name>

So if your remote is called "origin", and your branch is "turtles":

git reflog refs/remotes/origin/turtles
Jaime Bellmyer
  • 23,051
  • 7
  • 53
  • 50