Asked  7 Months ago    Answers:  5   Viewed   18 times

What's the simplest way to undo:

git reset HEAD~

Currently, the only way I can think of is doing a git clone http://... from a remote repo.

 Answers

44

Short answer:

git reset 'HEAD@{1}'

Long answer:

Git keeps a log of all ref updates (e.g., checkout, reset, commit, merge). You can view it by typing:

git reflog

Somewhere in this list is the commit that you lost. Let's say you just typed git reset HEAD~ and want to undo it. My reflog looks like this:

$ git reflog
3f6db14 HEAD@{0}: HEAD~: updating HEAD
d27924e HEAD@{1}: checkout: moving from d27924e0fe16776f0d0f1ee2933a0334a4787b4c
[...]

The first line says that HEAD 0 positions ago (in other words, the current position) is 3f6db14; it was obtained by resetting to HEAD~. The second line says that HEAD 1 position ago (in other words, the state before the reset) is d27924e. It was obtained by checking out a particular commit (though that's not important right now). So, to undo the reset, run git reset HEAD@{1} (or git reset d27924e).

If, on the other hand, you've run some other commands since then that update HEAD, the commit you want won't be at the top of the list, and you'll need to search through the reflog.

One final note: It may be easier to look at the reflog for the specific branch you want to un-reset, say master, rather than HEAD:

$ git reflog show master
c24138b master@{0}: merge origin/master: Fast-forward
90a2bf9 master@{1}: merge origin/master: Fast-forward
[...]

This should have less noise it in than the general HEAD reflog.

Tuesday, June 1, 2021
 
gMale
answered 7 Months ago
93

No you cannot force a file that is already committed in the repo to be removed just because it is added to the .gitignore

You have to git rm --cached to remove the files that you don't want in the repo. ( --cached since you probably want to keep the local copy but remove from the repo. ) So if you want to remove all the exe's from your repo do

git rm --cached /*.exe

(Note that the asterisk * is quoted from the shell - this lets git, and not the shell, expand the pathnames of files and subdirectories)

Tuesday, June 1, 2021
 
Slinky
answered 7 Months ago
41

You pushed to the default push target, git@github.com. This means, that git@github.com was a remote in you source repo.

That implies, that the refs deleted from the server would still be in the remote locally after the push. Do not update the remotes (!).

Verify this by doing

git branch -a

on the side you pushed from (local).

It will probably show the refs that were deleted from the remote server.

[to be continued]

You could do something like:

for-each-ref refs/remotes/origin | while read sha type name
do 
    git branch "rescue_$(basename "$name")" "$sha"
done

to recover the branches locally. They will be named prefixed with rescue_ just as a precaution (in case you get funny or conflicting ref names).

Replace origin with the name of your remote


Test script

In case you want to test the procedure in a controlled environment, here is my approach condensed to minimum steps (execute in an empty dir, e.g. /tmp/work)

git init A; (cd A; touch test; git add test; git commit -m initial; git branch test1; git branch test2; git branch test3)
git clone A B
(cd B; git push --mirror origin; git branch -a)
cd A
git for-each-ref refs/remotes/origin | while read sha type name; do git branch "rescue_$(basename "$name")" "$sha"; done
git branch -a

Note how in this version, I cd into A - which would be your github repo. You could git clone --mirror git@github.com:... local_rescue in order to get a suitable local version of that.

I recommend you play around getting to terms with the procedure before trying it out. It never hurts to backup your repositories along the way.

Sunday, August 15, 2021
 
inVader
answered 4 Months ago
19

If you tell git to ignore a directory, it will completely ignore everything inside that directory. This means git cannot match your exclude because git is simply not looking at it.

The only way to use excludes in a meaningful way is for a single directory, where you ignore everything but some folder like this:

/some/path/*
!/some/path/foo

This will ignore all entries but foo directly under /some/path.

But, most of the time it is much clearer to just explicitly ignore things than using excludes.

Thursday, August 19, 2021
 
Scott Kausler
answered 4 Months ago
86

Try running:

git config --system --unset-all core.askpass

to remove that configuration. You can then run git config --system --list to view the full list of system configurations to ensure it's gone.

Tuesday, November 16, 2021
 
Sionide21
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share