en en en en en en en fr en en en en en en en az en en tr es en en tr en en en en en en en en uk en en en en en en en en en en es en en en en en en en en en en jv en en jv en en jv en en tr en en en en en en en de en tr en en en en en en en en en en en en en en en en en en en en en en en en en en en es nl en en en en en fr en en en en en en en en en en en en en en pt en en en en en en en
In the course of development, there are times you want to look at or retrieve a file deleted sometime in the past – and you probably don’t know when it was deleted. I’ve written a simple git alias that makes it super easy.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Adds an alias called "unrm" to retrieve a pile or path deleted at any point in the repositories history.
git config –global alias.unrm '!COMMIT=$(git log -1 –pretty=%h — "$1"); git checkout $COMMIT^ — "$1"; echo "File: $1, was restored from commit $COMMIT"; git show -s $COMMIT'
hosted with ❤ by GitHub
So how does this work? If you don’t care, then just copy and paste the config line above – if you want to know what’s going on here, read on.
It uses some simple features of the “git log” and “git checkout” commands that everyone is already familiar with. Each can have a file path passed to them after a couple of dashes “–“. First, you need to find out when in the git history the file was removed, for that you can just use “git log” with a “–” and a path.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# this will be the commit where the file as deleted.
hosted with ❤ by GitHub
This works just like normal git-log, but narrows the log to show only commits that affect the given path – keep in mind that the path can be a specific file or an entire directory.
What if you want to actually retrieve that file? Well, you can do that with the “git checkout” command by doing basically the same thing. First copy the SHA1 hash of the last commit affecting the file you want to retrieve – this is important because you it will tell git-checkout where to look for the file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Recreate the file at path/to/file in the state in the state it was at
# just prior to having been deleted (made up commit hash for example)
git checkout 4efa6b0^ — path/to/file
hosted with ❤ by GitHub
The commit hash you copied from the “git log” output doesn’t actually contain the file, its just when the file was deleted because that commit is by definition the last commit to affect the file. To get the last state of the file before its removal you need to look to the commit immediately before it, thats what the “^” does, it looks one commit back.
So that a bunch of stuff to remember – although its fairly simple compared to some other more complex tasks in git – but I made the git alias to make it even easier. I think I originally came up with this alias an an answer on StackOverflow, but its been sitting around as a gist on my github account for a while. I’ll probably be sharing more stuff from gist in the future.
Better Git: Interact With a Branch, Without Checking it Out.
Posted: April 10, 2013 | Author: eddiemoya | Filed under: Better Git | 2 Comments
Tricks for interacting with a branch, without checking it out.
Browse a directory (like ls):
Syntax: git show [ref]:[path]
> git show master:your/path/
See contents of a file (command as above):
Syntax: git show [ref]:[filepath]
> git show master:your/path/file.php
Checkout a specific file or directory from a different branch:
Syntax: git checkout [ref] -- [path]
> git checkout master -- your/path/file.php
Note: There are other ways to do similar tasks such as `git ls-tree` and they may have more options. However I find these to be more accessible and easy to remember.
Better Git: git fetch not getting tags
Posted: February 21, 2013 | Author: eddiemoya | Filed under: Better Git | Leave a comment
I just ran into a little gotcha with regard how fetch handles tags. When it pulls down commits, you will usually see that it also pulls down tags. I was a little confused today when fetch was refusing to pull a tag that was clearly in the repository (“git ls-remote --tags“) lets you see tags available on the remote).
I kept running the fetch command but the tag wouldn’t get pulled down. The reason has to do with the way fetch works, it only fetches tags that are direct references to a commit that is in a branch being fetched. To get all tags regardless of what commits they reference use the fetch in the following way.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Passing the –tags argument makes fetch retrieve tags explicitly.
hosted with ❤ by GitHub
From the git manual (“git help fetch”):
-t, –tags Most of the tags are fetched automatically as branch heads are downloaded, but tags that do not point at objects reachable from the branch heads that are being tracked will not be fetched by this mechanism. This flag lets all tags and their associated objects be downloaded. The default behavior for a remote may be specified with the remote. .tagopt setting. See git-config(1).
This will effectively do the inverse of normal fetch. It will fetch all tags, and bring with is any necessary commits.
Hope this helps some poor confused folks out there a little bit of grief.
Better Git: How to find out what submodules there are in a different branch
Posted: February 5, 2013 | Author: eddiemoya | Filed under: Better Git | Leave a comment
Generally speaking Git is fantastic and easy to use – one of the few pain points is where submodules butt heads with branches.
Far from solving all the problems in related to this – I’ve found an easy way to find out what submodules are in a branch, commit, or tag without having to check that reference out. This method also shows you the commits that each submodule is currently pointing to.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Where   should be replaced with a branch name, tag name, or commit hash.
git ls-tree -rt   | grep 'commit [0-9A-z]'
hosted with ❤ by GitHub
The ls-tree command is fairly simple, its like running the ls unix command but includes git information – like the type of object each item is and the hash reference for that object. That command can also be used on a specific directory also by using  : . The -r flag makes it recursive so that is searches through all the subdirectories in the branch.
The second part of this is a simple grep command, that filters the results by those of type “commit”, which is how ls-tree represents submodules. I’ve included a pattern to match the word commit followed by the SHA1 hash – to avoid getting items that have the word commit as part of a folder or filename.
Hope this helps someone out there – it took me a while to figure out how to do this.
Media Categories 1.6 Beta
Git Smarter: Retrieve deleted files from history [ git unremove ]
VIM: Saving with sudo, without opening with sudo
Wooden 3D Printed WordPress Logos #wcchi
WP_Query: Get Posts by Relative Date
Follow me on Twitter
Incorrect Datetime Bug Fix
Follow Blog via Email
Enter your email address to follow this blog and receive notifications of new posts by email.
Join 255 other followers
Blog at WordPress.com. Mid Mo Design.
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.