{"id":7166,"date":"2016-07-04T10:00:32","date_gmt":"2016-07-04T01:00:32","guid":{"rendered":"http:\/\/www.skyarch.net\/blog\/?p=7166"},"modified":"2016-07-04T10:29:35","modified_gmt":"2016-07-04T01:29:35","slug":"some-tricks-with-git","status":"publish","type":"post","link":"https:\/\/www.skyarch.net\/blog\/some-tricks-with-git\/","title":{"rendered":"Some tricks with Git"},"content":{"rendered":"<p>As a Developer, we love to explore how other developers work. So now, let's take a look at some of the features that you might not familiar with, or at the possibilities that git provides!<\/p>\n<p>Git is a distributed version control system. It is a open-source code management tool. Everything you do is reversible. It doesn't force you to work in a particular way; makes it easy to experiment with new ideas not worry about breaking anything. It is easy to get the hang of as well. So get ready!<\/p>\n<h3><strong>Aliases<\/strong><\/h3>\n<p>Git lets you create aliases, which are shortcuts to other commands that will literally save you minutes a year in saved keystrokes. Stop wasting time typing long commands and make yourself a few useful aliases. Aliases can be made by adding them to your <code>.gitconfig<\/code> file or using the command-line<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit config --global alias.&lt;NAME&gt; &quot;&lt;COMMAND&gt;&quot;\r\n<\/pre>\n<p>Typing git checkout every time you wanted to see a new branch over and over has been a bit verbose.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit config --global alias.co checkout\r\n<\/pre>\n<p>Stage your changes and then use <code>git co branch<\/code>.<\/p>\n<p>Let\u2019s create a few aliases for our most common commands:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&#x5B;alias]\r\n\t\r\nds = diff --staged\r\nst = status -sb\r\nfup = log --since '1 day ago' --oneline --author &lt;YOUR_EMAIL&gt;\r\n\r\n# pretty one-line log with tags, branches and authors\r\nls = log --pretty=format:&quot;%C(yellow)%h %C(blue)%ad%C(red)%d %C(reset)%s%C(green) &#x5B;%cn]&quot; --decorate --date=short\r\n\r\n# a verbose ls, shows changed files too\r\nlsv = log --pretty=format:&quot;%C(yellow)%h %C(blue)%ad%C(red)%d %C(reset)%s%C(green) &#x5B;%cn]&quot; --decorate --date=short --numstat\r\n\r\n# some resets without explanation\r\nr = reset\r\nr1 = reset HEAD^\r\nr2 = reset HEAD^^\r\nrh = reset --hard\r\nrh1 = reset HEAD^ --hard\r\nrh2 = reset HEAD^^ --hard\r\n\r\n# basic shortcuts\r\ncp = cherry-pick\r\ncl = clone\r\nci = commit\r\nco = checkout\r\nbr = branch \r\ndiff = diff --word-diff\r\ndc = diff --cached\r\n\r\n# stash shortcuts\r\nsl = stash list\r\nsa = stash apply\r\nss = stash save\r\n\r\n# log related - thanks to @mwd410\r\nl = log \r\nlh = log --graph\r\nla = !git lh --date-order --all 2&gt; \/dev\/null\r\nlb = log --graph --simplify-by-decoration\r\nlba = !git lb --all \r\nh = !git --no-pager log --graph -n 15\r\na = !git --no-pager la -n 15\r\n<\/pre>\n<p>Git includes a long list of configuration options, all of which can be found in the <a href=\"https:\/\/www.kernel.org\/pub\/software\/scm\/git\/docs\/git-config.html\" target=\"_blank\">git-config manual<\/a>. Note that storing your global configurations in a plaintext file makes it incredibly easy to transfer your settings to a new Git installation: just copy <code>~\/.gitconfig<\/code> onto your new machine.<\/p>\n<h3><strong>Branches sorted by last commit<\/strong><\/h3>\n<p>The for-each-ref command will output a list for each branch and show the reference information for the last commit, or sort the list by date. I highly recommend making it an alias instead of typing this command each time.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit config --global alias.latest_commit &quot;for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short) &#x5B;%(committername)]'&quot;\r\n<\/pre>\n<p>then use;<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit latest_commit\r\n<\/pre>\n<h3><strong>Creating new branch with no history<\/strong><\/h3>\n<p>There is a very simple way to create a new branch in your repo that essentially has no history.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit checkout --orphan \r\n<\/pre>\n<h3><strong>Checkout to your last branch<\/strong><\/h3>\n<p>Let\u2019s say we had to make a quick fix to our project, and you don't want that in your feature branch. You'll need to stash your current changes, and checkout your master branch and make the fix there. Then switch back to your feature branch again.<\/p>\n<p>You'll never have to remember what you named that feature branch. There is a quick shortcut for switching to your last branch:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit checkout -\r\n<\/pre>\n<h3><strong>Branches that are merged or not<\/strong><\/h3>\n<p>If you want to see which local branches you have that are merged into the branch you are currently on, then all you need is:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit branch --merged\r\n<\/pre>\n<p>otherwise<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit branch --no-merged\r\n<\/pre>\n<p>You can mash this up with delete.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit branch --merged | xargs git branch -d\r\n<\/pre>\n<p>other wise<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit branch --no-merged | xargs git branch -d\r\n<\/pre>\n<h3><strong>Fetch a file from another branch without switching branches<\/strong><\/h3>\n<p>Let's say that you have a few branches that have various changes you've made. If you have changes in a file in some distant branch that you want to bring into your current working branch, then you could simply merge a single file in your current branch from another:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit checkout  -- path\/to\/file.rb\r\n<\/pre>\n<h3><strong>Merging branches without checkout<\/strong><\/h3>\n<p>Let's say we are working in a develop branch which is ahead of master by several commits. And we have a large repo so checkouts are time-consuming, or our compiler relies on timestamps and may think that a lot of files are dirty and need a rebuild. So we need another way .We want to merge develop to master.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit fetch &lt;remote&gt; &lt;sourceBranch&gt;:&lt;destinationBranch&gt;\r\n<\/pre>\n<p>then master will be fast-forwarded to develop.<\/p>\n<h3><strong>Interactive adding<\/strong><\/h3>\n<p>You are certainly familiar with accidentally modifying a single file for two different reasons without committing in between. Then we will use interactive adding. When you add a file with the -p command, you will be prompted at each logical change (i.e., successively edited lines will be grouped together).<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit add -p \r\n<\/pre>\n<h3><strong>Find something in your entire git history<\/strong><\/h3>\n<p>Sometimes, you need to hunt down a line of code you know you wrote but you don\u2019t find with plain old grep \u2014\u200amaybe someone deleted or changed it with a commit. You remember some parts of it but have no idea where and when you committed it. Fortunately git has your back on this. Let\u2019s fetch all commits ever then use git\u2019s internal grep subcommand to look for your string:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit rev-list --all | xargs git grep '' \r\ngit rev-list --all | xargs git grep -F '' # if you don't want to use regex\r\n<\/pre>\n<h3><strong>Git can autocorrect you<\/strong><\/h3>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit config --global help.autocorrect 1\r\n<\/pre>\n<h3><strong>Get a color-coded, one-line-per-commit log showing branches and tags<\/strong><\/h3>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit log --oneline --decorate\r\n<\/pre>\n<h3><strong>Finding whose to blame<\/strong><\/h3>\n<p>Often it can be useful to find out who changed a line of code in a file.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit blame FILE\r\n<\/pre>\n<h3><strong>Recovering a lost branch<\/strong><\/h3>\n<p>If you delete a branch with -D you can recreate it with:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ngit fsck\u200a--lost-found\r\n<\/pre>\n<p>It is dangling commit here is the lost HEAD (it will only be the HEAD of the deleted branch as the HEAD^ is referred to by HEAD so it\u2019s not dangling).<\/p>\n<p>There is so much more you can learn about Git, hopefully you\u2019ve learned extra commands to help you manage your project more smartly. With all of these convenient features, it\u2019s easy to get so caught up in designing the perfect workflow that you lose sight of Git\u2019s underlying purpose. If you ever find that Git is causing more harm than good, don\u2019t be scared to drop some of the advanced features and go back to the basics. But don\u2019t stop here; check out other resources to become a Git master! And the most powerful command as you learn; <code>man git--<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As a Developer, we love to explore how other developers work. So now, let&#8217;s take a look at some of the feature&#8230;<\/p>\n","protected":false},"author":1,"featured_media":7073,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"ja","_original_post":"7066","footnotes":""},"categories":[9],"tags":[],"class_list":{"0":"post-7166","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-dev","8":"ja"},"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/posts\/7166","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/comments?post=7166"}],"version-history":[{"count":4,"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/posts\/7166\/revisions"}],"predecessor-version":[{"id":7183,"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/posts\/7166\/revisions\/7183"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/media\/7073"}],"wp:attachment":[{"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/media?parent=7166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/categories?post=7166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyarch.net\/blog\/wp-json\/wp\/v2\/tags?post=7166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}