git – everyday issues

Retrieve a deleted stash

theory, atlassian

Unless you have a backup somewhere else, this is difficult. However stashes are stored as regular git objects and provided this was done recently then the commit object will still be there and not garbage collected yet, it just won’t have any references to it.

You can list all unreachable commits , but you have to drop to the command line (click Terminal on the toolbar). Then type:

git fsck --unreachable

This will show you all the commits which are not reachable by a branch / tag and which haven’t been garbage collected yet. Look for the ones that say ‘unreachable commit’, ignore the blobs. The chances are it will be the one closest the top, unless you’ve performed some other actions which created more unreachables. You can examine the commits by doing ‘git show <sha>’, and this should identify the stash, it’ll probably be called ‘On master: <your comment>’ or similar. Once you’ve found it, copy the SHA.

To recover this you then do:

git stash apply <sha>

Which will bring it back into your working copy.

Undo a git reset –hard HEAD~1?

git reset --hard HEAD~1

This morning I happened to do it twice, just to go back to an old commit, discarding the unwanted files I added with “git add .” However, there was no way to come back. That’s when this answer came to help.

#your current changes remain there until git gc comes into effect

#first do a reflog, that'll show you all changes made
$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2

#use the SHA to go back to the original commit
$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2

.gitignore-d some files, removed tracking from them, now wish to remove them from the repo ?

So, you’ve added the paths to .gitignore file. But those files are already in the remote repo (& your local too). There are 2 methods for accomplishing this (full blog & SO answer):

  1. RM CACHED method: Involves deleting the files. Be cautious and make a dry-run before deleting so that important files do not get affected. Dry run just tells you what actions will be taken, instead of taking them in reality.
git rm --cached -r foldername/* --dry-run
#optionally use pipe-grep file/folders that you consider important
git rm --cached -r foldername/* --dry-run | grep -E 'important|project|critical|foo|bar'

Bonus: read more about regular expressions with grep

If it is a folder, you’ve to recursively delete using the -r option:

git rm --cached -r foldername/*

If they’re individual files, execute this on each of them:

git rm --cached filename.extension

After this, make a commit & push changes. Let the history of deleting these stuff be in the repo, that won’t cause any harm.

2. Assume Unchanged method:

git update-index --assume-unchanged [path]

Did you get a src refspec master does not match any when pushing commits in git error while pushing to remote on a freshly cloned (& branched) repo?

Maybe you just need to commit :)
Bonus: Read about `--set-upstream` and `git push -u origin <local branch name>`


Working on a fork – Keeping A GitHub Fork Updated

# add another remote alias: called `upstream` pointed to the original repo
$ git remote add upstream
# rebase wrt original repo
$ git fetch upstream
$ git rebase upstream/master
# commit & push to your fork, then raise a `pull request`

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s