24

I have a thorough understanding of git, and the difference between pull, fetch, and merge. I have a remote that I track, fetch, and merge with occasionally, let say it's origin/master. What I'm looking to do is reverse the behavior of a 'git fetch'. It sounds goofy, but I want to un-update where my remote tracking branch points, to an older state, the state right before the last fetch. Is this possible?

For example, lets say this is my workflow...

git show origin/master # shows commit abc123

git fetch              # yay i got something!

git show origin/master # shows commit def456

mystery command goes here so that...

git show origin/master # shows commit abc123

It's kind of a weird thing to want, but I have a crontab that watches a git repo to detect when there's something to fetch, and I'm having issues debugging the script that performs some actions based on this behavior. Instead of waiting for origin/master to change, I'd like to change it myself so I can debug my script!

Mark Fisher
  • 965
  • 1
  • 11
  • 30
user2141094
  • 243
  • 1
  • 2
  • 4
  • 1
    It's not that weird ... I just fetched, and got a bunch of changes that I don't want and I want to do the same thing ... have my remote-tracking branch point to an older version of that repo (as if I had not fetched). I know those changes are not in my working directory ... I don't even want them on my remote-tracking branch. Thank you for asking this question and getting an answer in time for me to be able to refer to it : -) – Brenda J. Butler Mar 05 '15 at 19:46

4 Answers4

17

You want

git update-ref refs/remotes/origin/master refs/remotes/origin/master@{1}

update-ref wants the full spell on the ref it's updating because it's (much) lower level than the commands that respect ref-naming conventions.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • Awesome, that was exactly what I was looking for! One can say that this command does exactly "undo fetch". But I wonder what does {1} mean in the command? I wanted to undo fetch with 30+ new commits and {3} worked for me, not "30" – The Godfather Mar 27 '18 at 11:19
  • The @{} syntax is documented here: https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#_git_reflog . In short, `@{n}` means "n'th entry from reflog". `git log -g origin/master` shows the reflog of origin/master, with `@{n}` annotations. So `@{1}` means "before last fetch", assuming you run it right after a fetch. – thakis Dec 10 '19 at 13:01
2

This isn't a "reverse a git fetch" answer, but it seems your actual problem is how to programmatically "watch a repo for changes" without necessarily altering your repository in any way.

For this, you can use git fetch --dry-run. A dry run will not cause any changes to your repository, but if there are changes in the remote, then it will have some basic terminal output; if there are no changes there will not be any output. If you want to have this running as an automated script instead of a manual check, it should be relatively straightforward to create a simple bash script that tests git fetch --dry-run for output.

Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
1

I'm not sure if there's an actual git command to do it, and this is a big hackish, but...

echo $OLD_COMMIT > .git/refs/remotes/origin/master

should work

Dewey Sasser
  • 379
  • 2
  • 8
0

I hope this time I got what you want and I think it's this:

git rebase origin/master --onto origin/master^
Stephan
  • 1,639
  • 3
  • 15
  • 26