{"id":443,"date":"2014-02-20T14:32:45","date_gmt":"2014-02-20T13:32:45","guid":{"rendered":"http:\/\/hesmid.nl\/test\/?p=443"},"modified":"2019-07-17T16:21:57","modified_gmt":"2019-07-17T14:21:57","slug":"git-snippets-and-tricks","status":"publish","type":"post","link":"https:\/\/hesmid.nl\/test\/git-snippets-and-tricks\/","title":{"rendered":"Git snippets and tricks"},"content":{"rendered":"<h3>Read this:<\/h3>\n<p><em><a href=\"https:\/\/codewords.recurse.com\/issues\/two\/git-from-the-inside-out\">Git from the inside out<\/a><\/em><\/p>\n<h3>Look at this workflow:<\/h3>\n<p><a href=\"http:\/\/justinhileman.info\/git-pretty\/\">http:\/\/justinhileman.info\/git-pretty\/<\/a><\/p>\n<p><a href=\"https:\/\/hesmid.nl\/test\/wp-content\/uploads\/2014\/02\/git-pretty.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1296\" src=\"https:\/\/hesmid.nl\/test\/wp-content\/uploads\/2014\/02\/git-pretty-300x297.png\" alt=\"git-pretty\" width=\"300\" height=\"297\" srcset=\"https:\/\/hesmid.nl\/test\/wp-content\/uploads\/2014\/02\/git-pretty-300x297.png 300w, https:\/\/hesmid.nl\/test\/wp-content\/uploads\/2014\/02\/git-pretty-150x150.png 150w, https:\/\/hesmid.nl\/test\/wp-content\/uploads\/2014\/02\/git-pretty-1024x1015.png 1024w, https:\/\/hesmid.nl\/test\/wp-content\/uploads\/2014\/02\/git-pretty-60x60.png 60w, https:\/\/hesmid.nl\/test\/wp-content\/uploads\/2014\/02\/git-pretty.png 1692w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h3><\/h3>\n<h3>1.\u00a0Ignore files that are already tracked<\/h3>\n<ol>\n<li><strong>First commit any outstanding code changes<\/strong>,<\/li>\n<li>and then, run this command:<br \/>\n<code>git rm -r --cached .<\/code><br \/>\nThis removes everything from the <em>index<\/em><\/li>\n<li>then just run:<br \/>\n<code>git add .<\/code><\/li>\n<li>Commit it:<br \/>\n<code>git commit -m \".gitignore is now working\"<\/code><\/li>\n<\/ol>\n<p><!--more--><\/p>\n<h3>2. Edit an incorrect commit message in Git<\/h3>\n<pre lang=\"bash\">git commit --amend -m \"New commit message\"<\/pre>\n<p>If you&#8217;ve already pushed, just force push again:<\/p>\n<pre lang=\"bash\">git push -f origin branchname<\/pre>\n<p>Note: like rebasing, this is changing the history. If someone has cloned\/pulled from your repo between the original and rewritten history then they won&#8217;t be able to pull after the rewrite (for that branch).<\/p>\n<h3>3. Undo the last commit<\/h3>\n<pre lang=\"bash\">$ git commit ...              #(1)\n$ git reset --soft 'HEAD^'    #(2)\n$ edit                        #(3)\n$ git add ....                #(4)\n$ git commit -c ORIG_HEAD     #(5)<\/pre>\n<p>(1) This is what you want to undo<br \/>\n(2)This is most often done when you remembered what you just committed is incomplete, or you misspelled your commit message, or both. Leaves working tree as it was before &#8220;reset&#8221;. (The quotes may or may not be required in your shell)<br \/>\n(3)Make corrections to working tree files.<br \/>\n(4) Stage changes for commit.<br \/>\n(5) &#8220;reset&#8221; copies the old head to .git\/ORIG_HEAD; redo the commit by starting with its log message. If you do not need to edit the message further, you can give -C option instead.<\/p>\n<p>See <a href=\"http:\/\/stackoverflow.com\/a\/6866485\">this answer<\/a> on StackOverflow for a more elaborate explanation<\/p>\n<h3>4. Delete all changes from working directory including new untracked files.<\/h3>\n<pre lang=\"bash\">git reset --hard # removes staged and working directory changes\ngit clean -f -d # remove untracked files\n\n\n( git clean -f -x -d # CAUTION: as above but removes ignored files like config. )<\/pre>\n<h3>5. Force pull<\/h3>\n<p>Force an overwrite of local files on a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Git_%28software%29\">Git<\/a> pull?<\/p>\n<p>I did this succesfully on my server where I force pulled from a bare repository (on the same server). \u00a0Source:\u00a0<a href=\"http:\/\/stackoverflow.com\/a\/8888015\">http:\/\/stackoverflow.com\/a\/8888015<\/a><\/p>\n<pre><code>git fetch --all\ngit reset --hard origin\/master\n<\/code><\/pre>\n<p><strong>Explanation:<\/strong><\/p>\n<p><code>git fetch<\/code> downloads the latest from remote without trying to merge or rebase anything.<\/p>\n<p>Then the <code>git reset<\/code> resets the master branch to what you just fetched. The <code>--hard<\/code> option changes all the files in your working tree to match the files in <code>origin\/master<\/code>, so if you have any local changes, they will be lost. With or without <code>--hard<\/code>, any local commits that haven&#8217;t been pushed will be lost.<\/p>\n<p>If you have any files that are <em>not<\/em> tracked by Git (e.g. uploaded user content), these files will not be affected.<\/p>\n<h3>6. Force Push<\/h3>\n<p>You can completely specify specific branches and a remote:<\/p>\n<pre lang=\"bash\">git push   -f\ngit push origin master -f # Example<\/pre>\n<p>When the branch to push branch is omitted, Git will figure it out based on your config settings. In Git versions after 2.0, a new repo will have default settings to push the currently checked-out branch:<\/p>\n<pre lang=\"bash\">git push  -f\ngit push origin -f # Example<\/pre>\n<p>When both the remote and the branch are omitted, the behavior of just git push &#8211;force is determined by your push.default Git config settings:<\/p>\n<pre lang=\"bash\">git push --force<\/pre>\n<p>As of Git 2.0, the default setting, simple, will basically just push your current branch to its upstream remote counter-part. The remote is determined by the branch&#8217;s branch..remote setting, and defaults to the origin repo otherwise.<\/p>\n<h3>7. Change remote origin<\/h3>\n<pre lang=\"bash\">git remote set-url origin [URL]<\/pre>\n<h3>8. Remove submodule<\/h3>\n<ol>\n<li>Delete the relevant section from the\u00a0<code>.gitmodules<\/code>\u00a0file. \u00a0The section would look similar to:\n<pre class=\" language-shell\"><span class=\"token punctuation\">[<\/span>submodule <span class=\"token string\">\"vendor\"<\/span><span class=\"token punctuation\">]<\/span>\n\tpath <span class=\"token operator\">=<\/span> vendor\n\turl <span class=\"token operator\">=<\/span> git<span class=\"token punctuation\">:<\/span><span class=\"token operator\">\/<\/span><span class=\"token operator\">\/<\/span>github<span class=\"token punctuation\">.<\/span>com<span class=\"token operator\">\/<\/span>some<span class=\"token operator\">-<\/span>user<span class=\"token operator\">\/<\/span>some<span class=\"token operator\">-<\/span>repo<span class=\"token punctuation\">.<\/span>git<\/pre>\n<\/li>\n<li>Stage the\u00a0<code>.gitmodules<\/code>\u00a0changes via command line using:<code>git add .gitmodules<\/code><\/li>\n<li>Delete the relevant section from\u00a0<code>.git\/config<\/code>, which will look like:\n<pre class=\" language-shell\"><span class=\"token punctuation\">[<\/span>submodule <span class=\"token string\">\"vendor\"<\/span><span class=\"token punctuation\">]<\/span>\n\turl <span class=\"token operator\">=<\/span> git<span class=\"token punctuation\">:<\/span><span class=\"token operator\">\/<\/span><span class=\"token operator\">\/<\/span>github<span class=\"token punctuation\">.<\/span>com<span class=\"token operator\">\/<\/span>some<span class=\"token operator\">-<\/span>user<span class=\"token operator\">\/<\/span>some<span class=\"token operator\">-<\/span>repo<span class=\"token punctuation\">.<\/span>git<\/pre>\n<\/li>\n<li>Run\u00a0<code>git rm --cached path\/to\/submodule<\/code>\u00a0. \u00a0Don&#8217;t include a trailing slash &#8212; that will lead to an error.<\/li>\n<li>Run\u00a0<code>rm -rf .git\/modules\/submodule_name<\/code><\/li>\n<li>Commit the change<\/li>\n<li>If you want to keep the submodule files in your repo:\n<ol>\n<li>rm -rf path\/to\/submodule\/.git<\/li>\n<li>git add .<\/li>\n<\/ol>\n<\/li>\n<li>Otherwise:<br \/>\nDelete the now untracked submodule files <code>rm -rf path\/to\/submodule<\/code><\/li>\n<\/ol>\n<h3>9.\u00a0Push a particular commit<\/h3>\n<p><a href=\"http:\/\/stackoverflow.com\/a\/3230241\" target=\"_blank\" rel=\"noopener\">source<\/a><\/p>\n<pre lang=\"bash\">git push &lt;remotename&gt; &lt;commit SHA&gt;:&lt;remotebranchname&gt;<\/pre>\n<p>should do the trick. Example:<\/p>\n<pre lang=\"bash\">git push origin 712acff81033eddc90bb2b45e1e4cd031fefc50f:master<\/pre>\n<p>Note that this pushes all commits up to and including the commit you choose. If you don&#8217;t want that to happen, you should first use <code>git rebase -i<\/code> to re-order the commits.<\/p>\n<h3>10.\u00a0Clone a particular release\/version<\/h3>\n<p>&#8220;reset&#8221; your repository to any commit you want (e.g. 1 month ago).<br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/3555107\/git-clone-particular-version-of-remote-repository\">source<\/a><\/p>\n<p>Use <a href=\"http:\/\/git-scm.com\/docs\/git-reset\">git-reset<\/a> for that:<\/p>\n<pre><code>git clone [remote_address_here] my_repo\ncd my_repo\ngit reset --hard [ENTER HERE THE COMMIT HASH YOU WANT]\n\n<\/code><\/pre>\n<table  class=\" table table-hover\" >\n<tbody data-remaining-comments-count=\"0\" data-canpost=\"false\" data-cansee=\"true\" data-comments-unavailable=\"false\" data-addlink-disabled=\"true\">\n<tr id=\"comment-24057766\" class=\"comment \">\n<td class=\"comment-text\">\n<div class=\"comment-body\"><span class=\"comment-copy\">why would you not do a simple checkout of the wanted commit?<\/span> \u2013\u00a0<a class=\"comment-user\" title=\"1,418 reputation\" href=\"http:\/\/stackoverflow.com\/users\/568844\/nemoo\">nemoo<\/a> <span class=\"comment-date\" dir=\"ltr\"><a class=\"comment-link\" href=\"http:\/\/stackoverflow.com\/questions\/3555107\/git-clone-particular-version-of-remote-repository#comment24057766_3555202\"><span class=\"relativetime-clean\" title=\"2013-05-23 10:44:32Z\">May 23 &#8217;13 at 10:44<\/span><\/a><\/span><\/div>\n<\/td>\n<\/tr>\n<tr id=\"comment-24070255\" class=\"comment \">\n<td class=\"comment-actions\"><span class=\"comment-copy\">Because you will be on the &#8220;detached HEAD&#8221; state after checkout to a particular commit.<\/span> \u2013\u00a0<a class=\"comment-user\" title=\"2,951 reputation\" href=\"http:\/\/stackoverflow.com\/users\/72824\/rui-carneiro\">Rui Carneiro<\/a><span class=\"comment-date\" dir=\"ltr\"><a class=\"comment-link\" href=\"http:\/\/stackoverflow.com\/questions\/3555107\/git-clone-particular-version-of-remote-repository#comment24070255_3555202\"><span class=\"relativetime-clean\" title=\"2013-05-23 16:06:31Z\">May 23 &#8217;13 at 16:06<\/span><\/a><\/span><\/td>\n<td class=\"comment-text\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre><code>\u00a0<\/code><\/pre>\n<h3>11. Use Sublime Text 3 as core editor<\/h3>\n<p><a href=\"http:\/\/stackoverflow.com\/a\/9408117\">Source<\/a><\/p>\n<p><a href=\"http:\/\/www.sublimetext.com\/3\">Sublime Text 3<\/a> (Build 3065) added the <code>subl.exe<\/code> command line helper. Use <code>subl.exe -h<\/code> for the options available to you. I have <code>hot_exit: true<\/code> and <code>remember_open_files: true<\/code> set in my Sublime Text user settings. I have found the following git config to work well for me.<\/p>\n<pre><code>git config --global core.editor \"'c:\/program files\/sublime text 3\/subl.exe' -w\"\n<\/code><\/pre>\n<p>With this git config the a new tab is opened in my editor. I edit my commit message, save the tab and close it (<code>CTRL+w<\/code>). Git will wait until the tab is closed to continue its work.<\/p>\n<h3>12.\u00a0Undo <code>git add<\/code> for a file<\/h3>\n<p><code>\u00a0git reset HEAD &lt;file&gt;<\/code><\/p>\n<h3>13. Delete the history of a repo<\/h3>\n<p><a href=\"http:\/\/stackoverflow.com\/a\/26000395\">http:\/\/stackoverflow.com\/a\/26000395<\/a><br \/>\nIf you want to delete all your commit history but keep the code in its current state, it is very safe to do it as in the following:<\/p>\n<ol>\n<li>Checkout<code>git checkout --orphan latest_branch<\/code><\/li>\n<li>Add all the files<code>git add -A<\/code><\/li>\n<li>Commit the changes<code>git commit -am \"commit message\"<\/code><\/li>\n<li>Delete the branch<code>git branch -D master<\/code><\/li>\n<li>Rename the current branch to master<code>git branch -m master<\/code><\/li>\n<li>Finally, force update your repository<code>git push -f origin master<\/code><\/li>\n<\/ol>\n<h3>14.\u00a0Diff the same file between two different commits on the same branch<\/h3>\n<p><a href=\"https:\/\/stackoverflow.com\/a\/3338145\">https:\/\/stackoverflow.com\/a\/3338145<\/a><\/p>\n<p>To see the difference for a file &#8220;main.c&#8221; between now and two commits back, here are three equivalent commands:<\/p>\n<p><code>git diff HEAD^^ HEAD main.c<\/code><br \/>\n<code>git diff HEAD^^..HEAD -- main.c<\/code><br \/>\n<code>git diff HEAD~2 HEAD -- main.c<\/code><\/p>\n<h3>15. Error when pushing to bare repository<\/h3>\n<p>When you get something like this:<\/p>\n<p><code>error: failed to push some refs to 'git@github.com:519ebayproject\/519ebayproject.git'<br \/>\nhint: Updates were rejected because the tip of your current branch is behind<br \/>\nhint: its remote counterpart. Merge the remote changes (e.g. 'git pull')<br \/>\nhint: before pushing again.<br \/>\nhint: See the 'Note about fast-forwards' in 'git push --help' for details.<\/code><\/p>\n<p>The simplest solution is to force push the repo as described before:<\/p>\n<p>git push origin master -f<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Read this: Git from the inside out Look at this workflow: http:\/\/justinhileman.info\/git-pretty\/ 1.\u00a0Ignore files that are already tracked First commit any outstanding code changes, and then, run this command: git rm -r &#8211;cached . This removes everything from the index then just run: git add . Commit it: git commit -m &#8220;.gitignore is now working&#8221;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7],"tags":[3],"acf":[],"_links":{"self":[{"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/posts\/443"}],"collection":[{"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/comments?post=443"}],"version-history":[{"count":38,"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/posts\/443\/revisions"}],"predecessor-version":[{"id":13680,"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/posts\/443\/revisions\/13680"}],"wp:attachment":[{"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/media?parent=443"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/categories?post=443"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hesmid.nl\/test\/wp-json\/wp\/v2\/tags?post=443"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}