{"id":550,"date":"2012-03-13T17:34:59","date_gmt":"2012-03-13T14:34:59","guid":{"rendered":"http:\/\/yoda\/wordpress\/?p=550"},"modified":"2018-10-03T10:42:24","modified_gmt":"2018-10-03T07:42:24","slug":"become-a-git-pro","status":"publish","type":"post","link":"https:\/\/blog.nssy.org\/?p=550","title":{"rendered":"Become a GIT Pro"},"content":{"rendered":"<p>Once you have created an account on github, you will need to set it up so that you can use it with your linux account. First Step is to create a ssh private\/public keys for using in github.<\/p>\n<hr id=\"system-readmore\" \/>\n<p><code class=\"prettyprint lang-sh linenums\">cd ~\/.ssh<br \/>\nssh-keygen -t rsa -C 'salasiapro@yahoo.com'<br \/>\n<\/code> Now save this as id_rsa_github in the .ssh folder in your home directory You will now have in your .ssh folder a file called id_rsa_github This is the file we will need to copy the contents over to github.com under your ssh keys (provide link here). Now we create a config file in the .ssh folder to tell git which key you use when connecting to github <code class=\"prettyprint lang-sh linenums\">gedit ~\/.ssh\/config<br \/>\n<\/code> and add the contents<\/p>\n<pre>Host github.com\r\n    HostName github.com\r\n    User git\r\n    IdentityFile ~\/.ssh\/id_rsa_github<\/pre>\n<h3>Setup Global Information for github<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git config --global user.name \"Firstname Lastname\"<br \/>\ngit config --global user.email \"your_email@youremail.com\"<br \/>\ngit config --global github.user username<br \/>\ngit config --global github.token 0123456789yourf0123456789token<br \/>\n<\/code> Note you will use the token you get from the github Now its time to start a new git project.<\/p>\n<h3>Create a new project on git<\/h3>\n<p>Mine is called firstgitproject On the teminal, go to the local folder of your project. <code class=\"prettyprint lang-sh linenums\">cd ~\/Projects\/firstgitproject<br \/>\n<\/code><\/p>\n<h3>First Time Commit<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git init<br \/>\ntouch README<br \/>\ngit add *<br \/>\ngit commit -m 'first commit'<br \/>\ngit remote add origin git@github.com:yourgitusername\/firstgitproject.git<br \/>\ngit push -u origin master<br \/>\n<\/code> Warning, starting git 2.0 (mid 2013), git add will not include unstaged (deleted) files. If you want to stage deleted files under your current path then you need to use <code class=\"prettyprint lang-sh linenums\">git add -u .<\/code><\/p>\n<h3>For the subsequent commits<\/h3>\n<p>you do <code class=\"prettyprint lang-sh linenums\">git add file_that_has_changed<br \/>\ngit commit or git commit -a<br \/>\ngit push origin master<br \/>\n<\/code><\/p>\n<h3>Adding a second remote<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git remote add [alias] [url]<\/code> note alias has to be unique (so if you used origin in the first remote, you will need to use something else for the alias)<br \/>\n  Also not that url is preferable in the format of user@host:repo.git<\/p>\n<h3>Configure to push to multiple remotes<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git remote set-url origin --push --add user1@host1:repo1.git<br \/>\ngit remote set-url origin --push --add user2@host2:repo2.git<\/code> <\/p>\n<h3>Display Configured remotes<\/h3>\n<p>\n  <code class=\"prettyprint lang-sh linenums\">git remote -v show<\/code>\n<\/p>\n<h3>Changing remote to a different location<\/h3>\n<p>Delete the current remote reference with <code class=\"prettyprint lang-sh linenums\">git remote rm origin<\/code> Add the new remote <code class=\"prettyprint lang-sh linenums\">git remote add origin (URL to new remote)<\/code> <\/p>\n<h3>Pushing<\/h3>\n<p>initial push to new remote <code class=\"prettyprint lang-sh linenums\">git push origin +HEAD<\/code><\/p>\n<h3>Cloning<\/h3>\n<p>Clone an already existing project https <code class=\"prettyprint lang-sh linenums\">git clone https:\/\/github.com\/nssy\/Project<\/code> ssh <code class=\"prettyprint lang-sh linenums\">git@github.com:nssy\/Project.git<\/code><\/p>\n<h3>Branching<\/h3>\n<p>Take a look at<a title=\"Git Branching\" href=\"https:\/\/git-scm.com\/book\/en\/v2\/Git-Branching-Basic-Branching-and-Merging\" target=\"_blank\"> https:\/\/git-scm.com\/book\/en\/v2\/Git-Branching-Basic-Branching-and-Merging<\/a><\/p>\n<p>Create and switch<\/p>\n<p><code>git checkout -b new_branch_name<\/code><\/p>\n<p>Long Form of creating and switching<\/p>\n<p><code class=\"prettyprint lang-sh linenums\">git branch experiment<br \/>\ngit checkout experiment<br \/>\n<\/code> Make Changes <code class=\"prettyprint lang-sh linenums\">git add .<br \/>\ngit commit -m \"my first branch commit\"<br \/>\ngit push origin experiment<br \/>\n<\/code> Or if set globally to push current branch git push<\/p>\n<h4>Adding Remote Branches to local repo<\/h4>\n<p><code class=\"prettyprint lang-sh linenums\">git branch remote_branch origin\/remote_branch<\/code><\/p>\n<h4>Deleting Branches<\/h4>\n<p><code class=\"prettyprint lang-sh linenums\"><br \/>\ngit branch -D branchname<br \/>\ngit push origin --delete branchname<br \/>\n<\/code> or <code class=\"prettyprint lang-sh linenums\">git push [remotename] [localbranch]:[remotebranch]<br \/>\n<\/code> If you leave off the [localbranch] portion, then you\u2019re basically saying, &#8220;Take nothing on my side and make it be [remotebranch].&#8221; in short <code class=\"prettyprint lang-sh linenums\">git push origin :branch<br \/>\n<\/code><\/p>\n<h4>Start Tracking a Remote Branch<\/h4>\n<p><code class=\"prettyprint lang-sh linenums\">git branch --set-upstream new-remote-branch-name origin\/new-remote-branch-name<\/code><\/p>\n<h3>Fetching &amp; Pulling<\/h3>\n<p>The fetch commands only updates the origin\/master. This means that you will need to merge the local branches manually. Note: Fetch does not affect your local files. It is recommended to always fetch often (Any time you want to work on your project). <code class=\"prettyprint lang-sh linenums\">git fetch<\/code> git pull mirrors the remote branch and the local branch you are currently in. It is equivalent of a fetch and a merge <code class=\"prettyprint lang-sh linenums\">git pull<\/code><\/p>\n<h3>Merging<\/h3>\n<p>Switching back to branch you want to merge (for my case master) <code class=\"prettyprint lang-sh linenums\">git checkout master<\/code>then do a merge <code class=\"prettyprint lang-sh linenums\">git merge experiment<br \/>\ngit push<br \/>\n<\/code> this will update the <strong>master<\/strong> branch with all the code from <strong>experiment<\/strong> branch<\/p>\n<h3>Fetch &amp; Merge<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git checkout master<br \/>\ngit remote add kneath git:\/\/github.com\/kneath\/jobs.git<br \/>\ngit fetch kneath<br \/>\ngit merge kneath\/error-page<br \/>\ngit push origin master<br \/>\n<\/code><\/p>\n<h3>Merging (Advanced)<\/h3>\n<p>supose we have two branches main is called nssy-dev and the updated one is called experimental. Further suppose that changes have been made on the same file in both branches. In such a case merging needs to be done in such a way that we end up an up to date file with both accepted changes from both branches. <b>(Warning: Running git merge with uncommitted changes is discouraged: while possible, it leaves you in a state that is hard to back out of in the case of a conflict.)<\/b> Begin the merge process <code class=\"prettyprint lang-sh linenums\">git checkout nssy-dev<\/code><code class=\"prettyprint lang-sh linenums\">git merge experimental<\/code> Now you need to view all the changes <code class=\"prettyprint lang-sh linenums\">git mergetool<\/code> Merge Types merge tool candidates: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis bc3 emerge vimdiff Abort a merge <code class=\"prettyprint lang-sh linenums\">git merge --abort<\/code><\/p>\n<h3>Patch and Apply<\/h3>\n<p>The fetch and merge approach works great when you\u2019re working on a team or repeatedly applying changes from the same small group of people. Another approach that\u2019s a bit quicker in one-off cases is to use git-am. Every pull request has a .patch URL where you can grab a textual patch file to feed into the git-am command: <code class=\"prettyprint lang-sh linenums\">git checkout master<br \/>\ncurl https:\/\/github.com\/github\/jobs\/pull\/25.patch | git am<br \/>\ngit push origin master<br \/>\n<\/code> Take into account that if you are using a private repository, the patch cannot be downloaded anonymously by curl, so you have to save it through your browser, and execute: <code class=\"prettyprint lang-sh linenums\">git checkout master<br \/>\ngit am \/location\/of\/patch\/25.patch<br \/>\ngit push origin master<br \/>\n<\/code><\/p>\n<h3>Configuration<\/h3>\n<p>Set git Push only the current branch (globally) <code class=\"prettyprint lang-sh linenums\">git config --global push.default current<\/code><\/p>\n<h3>Read more on Configuration<\/h3>\n<p>http:\/\/kernel.org\/pub\/software\/scm\/git\/docs\/git-config.html<\/p>\n<h3>Exclude folder of files from a commit<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git rm -r --cached folder\/*<\/code> or you can create the file .gitignore and add the path to exclude into .gitignore (as a line)<\/p>\n<h3>Shows all the changes between the working directory and HEAD<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git diff HEAD<\/code><\/p>\n<p>Shows all the changes between the working directory and HEAD (which includes changes in the index). This shows all the changes since the last commit, whether or not they have been staged for commit or not.<\/p>\n<h3>Common Errors<\/h3>\n<p>If you receive an error like this: error: Your local changes to &#8216;project_name&#8217; would be overwritten by merge. Aborting. Please, commit your changes or stash them before you can merge. You can &#8216;stash&#8217; your local changes and revert them later by doing: <code class=\"prettyprint lang-sh linenums\">git stash save \"comment goes here - why am I saving this?\"<\/code> Then you can do a pull again. To restore the stash from earlier do: <code class=\"prettyprint lang-sh linenums\">git stash list<\/code><code class=\"prettyprint lang-sh linenums\">git stash show stash@{0}<\/code><em>or if you need to see as stash as a patch<\/em><code class=\"prettyprint lang-sh linenums\">git stash show -p stash@{0}<\/code> Using Stashes <code class=\"prettyprint lang-sh linenums\">git stash pop<\/code><em>NB: pop removes the particular stash from list of stashes<\/em><code class=\"prettyprint lang-sh linenums\">git stash apply<\/code><em>NB: apply leaves a copy of the stash<\/em> Delete Stashes <code class=\"prettyprint lang-sh linenums\">git stash drop stash@{0}<\/code> Clear stashes <code class=\"prettyprint lang-sh linenums\">git stash clear<\/code><\/p>\n<h3>Reset Last commit<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git reset --hard HEAD<\/code> or <code class=\"prettyprint lang-sh linenums\">git reset --hard HEAD~1<\/code> for an even earlier reset <code class=\"prettyprint lang-sh linenums\">git reset --hard HEAD~n<\/code><em>where n is the number of commits behind you want to move to<\/em> or <code class=\"prettyprint lang-sh linenums\">git reset --hard HEAD^^<\/code> then <code class=\"prettyprint lang-sh linenums\">git push origin HEAD --force<\/code><\/p>\n<h3>Commands to explore<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git log --graph --oneline --all --decorate<\/code><code class=\"prettyprint lang-sh linenums\">git mergetool<\/code><\/p>\n<h3>Differenciate between branches\/commits<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git diff origin\/master..master<br \/>\n<\/code><\/p>\n<h3>View Commit log for a branch<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git log --oneline origin\/master<br \/>\n<\/code><\/p>\n<h3>Move to a previous specific commit<\/h3>\n<p><b>Please be cautious about this as all subsequent commits will be removed. But new files will remain intact.<br \/>Uncommited changes will also be overwritten.<\/b><code class=\"prettyprint lang-sh linenums\">git reset --hard db322e6<\/code><i>where <b>db322e6<\/b> is the commit id<\/i><\/p>\n<h3>Fix a commit before pushing<\/h3>\n<p>Make your changes then;<\/p>\n<p><code class=\"prettyprint lang-sh linenums\">git add .<\/code><\/p>\n<p><code class=\"prettyprint lang-sh linenums\">git commit --amend -m \"your new message\"<\/code><i>Fix author information. Sometimes this is necessary when you find yourself commiting before setting up your git username and email<\/i><code class=\"prettyprint lang-sh linenums\">git commit --amend --reset-author<\/code><\/p>\n<h3>Fix an older commit (that has been pushed)<\/h3>\n<p><b>Please be cautious about this as all subsequent commits will be removed. But new files will remain intact.<br \/>Uncommited changes will also be overwritten.<\/b><code class=\"prettyprint lang-sh linenums\">git reset --hard -c &lt;sha1&gt;<br \/>\ngit commit -m \"The message you wanted to use\"<br \/>\ngit push -f<br \/>\n<\/code><i>Then now do a full add and push<\/i><code class=\"prettyprint lang-sh linenums\">git add<br \/>\ngit commit -sm \"Some intelligent message\"<br \/>\ngit push<br \/>\n<\/code><\/p>\n<h3>Tagging<\/h3>\n<h4>Listing Your Tags<\/h4>\n<p><code class=\"prettyprint lang-sh linenums\">git tag<\/code><\/p>\n<h4>Create Annotated Tags<\/h4>\n<p><code class=\"prettyprint lang-sh linenums\">git tag -a v1.4 -m 'my version 1.4'<\/code><i>signed Annotated tags<\/i><code class=\"prettyprint lang-sh linenums\">git tag -s v1.4 -m 'my version 1.4'<\/code><\/p>\n<h4>Create Lightweight Tags<\/h4>\n<p><code class=\"prettyprint lang-sh linenums\">git tag v1.4-lw<\/code><\/p>\n<h4>Tag a commit<\/h4>\n<p><code class=\"prettyprint lang-sh linenums\">git tag -a v1.2 -m 'version 1.2' 9fceb02<\/code><\/p>\n<h4>Sharing Tags<\/h4>\n<p>By default, the git push command doesn\u2019t transfer tags to remote servers. you need to specify already created tag when pushing to remote <code class=\"prettyprint lang-sh linenums\">git push origin v1.5<\/code><\/p>\n<h5>Push all tags<\/h5>\n<p><code class=\"prettyprint lang-sh linenums\">git push origin --tags<\/code><\/p>\n<h5>Delete tag<\/h5>\n<p><code class=\"prettyprint lang-sh linenums\">git tag -d v1.1<\/code><\/p>\n<p>Enable Pushing of git commits &#038; tags simultaneously <code class=\"prettyprint lang-sh linenums\">git config --global push.followTags true<\/code><\/p>\n<h3>Git Aliases<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git config --global alias.co checkout<br \/>\ngit config --global alias.br branch<br \/>\ngit config --global alias.ci commit<br \/>\ngit config --global alias.st status<br \/>\ngit config --global alias.visual '!gitg'<br \/>git config --global alias.a \"add -A\"<br \/>\ngit config --global alias.logg \"log --graph --decorate --oneline --abbrev-commit\"<br \/>\n<\/code><\/p>\n<p>More Aliases (For viewing pretty Logs)<\/p>\n<p><code class=\"prettyprint lang-sh linenums\">git config --global alias.lg \"log --graph --pretty=format:'%Cred%h%Creset - %C(bold blue)(%cr) %C(bold cyan)%ad %C(bold white)%d%Creset %s %C(bold yellow)&lt;%an&gt;%Creset' --abbrev-commit --date=short\"<br \/>\n<\/code><\/p>\n<p><code class=\"prettyprint lang-sh linenums\">git config --global alias.l \"log --date-order --date=short --graph --full-history --pretty=format:'%x08%x09%C(red)%h %C(bold cyan)%ad %C(bold blue)(%cr) %C(bold yellow)&lt;%aN&gt;%C(reset)%C(bold yellow)%d %C(reset)%s'\"<br \/><\/code><\/p>\n<p>More Aliases (A more useful git diff)<\/p>\n<p><code class=\"prettyprint lang-sh linenums\">git config --global alias.truediff \"diff --ignore-space-at-eol -b -w --ignore-blank-lines\"<br \/><\/code><\/p>\n<h4>Other useful Aliases (My own Preference)<\/h4>\n<p><code class=\"prettyprint lang-sh linenums\">git config --global alias.master \"checkout master\"<br \/>\ngit config --global alias.ss \"stash save\"<br \/>\ngit config --global alias.sp \"stash pop\"<\/code><br \/>\n<i>Amend with the same message (very convenient)<\/i><br \/>\n<code class=\"prettyprint lang-sh linenums\">git config --global alias.amend \"log -n 1 --pretty=tformat:%s%n%n%b | git commit -F - --amend\"<\/code><br \/>\n<i>Unstage a file<\/i><br \/>\n<code class=\"prettyprint lang-sh linenums\">git config --global alias.unstage \"restore --staged\"<\/code>\n<\/p>\n<h3>Other useful commands<\/h3>\n<p><code class=\"prettyprint lang-sh linenums\">git remote -v<br \/>\ngit branch -r<br \/>\ngit branch -a<br \/>\ngit checkout -b branch_name origin\/branch_name<br \/>\ngit push origin --delete branch_to_delete<br \/>\ngit log -p branch_name..origin\/branch_name<br \/>\ngit log --format=\"%an\" version1..HEAD | sort -u<br \/>\n<\/code><\/p>\n<h3>grep git commits for a certain word<\/h3>\n<p>If you want to find all commits where commit message contains given word, use <code class=\"prettyprint lang-sh linenums\">git log --grep=word<\/code> for all branches <code class=\"prettyprint lang-sh linenums\">git log --all --grep=word<\/code> If you want to find all commits where &#8220;word&#8221; was added or removed (to be more exact: where number of occurences of &#8220;word&#8221; changed), i.e. search the commit contents, use so called &#8216;pickaxe&#8217; search with <code class=\"prettyprint lang-sh linenums\">git log -Sword<\/code> to look for differences whose added or removed line matches &#8220;word&#8221; (also commit contents). <code class=\"prettyprint lang-sh linenums\">git log -Gword<\/code><\/p>\n<h3>check out a pull request<\/h3>\n<p>When someone sends you a pull request from a fork or branch of your repository, you can merge it locally to resolve a merge conflict or to test and verify the changes before merging it<\/p>\n<p><a title=\"Checking out pull requests locally\" href=\"https:\/\/docs.github.com\/en\/pull-requests\/collaborating-with-pull-requests\/reviewing-changes-in-pull-requests\/checking-out-pull-requests-locally\" target=\"_blank\">Reference: Checking out pull requests locally <\/a><\/p>\n<p> Long story short, you do<\/p>\n<p><code>git fetch origin pull\/1\/head:pr1-author-x<\/code><\/p>\n<p>git will create a new branch pr1-author-x in your local clone with the contents of pull\/1\/head<\/p>\n<h3>Migrating origins<\/h3>\n<p>Say you have a local git repository or you want to move all git info eg. commits branches etc.<\/p>\n<p>Create a bare project on the server you want to host and get the git url for it<br \/>\neg.<\/p>\n<pre>git@gitlab.com:nssy\/imported-project.git<\/pre>\n<p>Go to local git folder<br \/>Now change the remote with the command:<\/p>\n<p><code>git remote set-url origin git@gitlab.com:nssy\/imported-project.git<\/code><\/p>\n<p>You can view the remotes with the command:<\/p>\n<p><code>git remote -v<\/code><\/p>\n<p>After that you will need to push all the branches<\/p>\n<p>Start by pushing to master with the command:<\/p>\n<p><code>git push -u origin master<\/code><\/p>\n<p>After that you will need to checkout all other subsequet branches and push the as you wish<\/p>\n<h3>Useful Resources<\/h3>\n<p><a title=\"Git - Tagging\" href=\"http:\/\/git-scm.com\/book\/en\/Git-Basics-Tagging\" target=\"_blank\">GIT Basics on Tagging <\/a><br \/><a title=\"Power Up\" href=\"http:\/\/oli.jp\/2012\/git-powerup\/\" target=\"_blank\">Git config powerup with aliases, diff &amp; log<\/a><br \/><a title=\"Advanced Alias Examples\" href=\"http:\/\/www.reddit.com\/r\/programming\/comments\/13m900\/must_have_git_aliases_advanced_examples_be\/\" target=\"_blank\">Advanced Alias Examples<\/a><br \/><a title=\"Tips &amp; Tricks\" href=\"http:\/\/git-scm.com\/book\/en\/Git-Basics-Tips-and-Tricks\" target=\"_blank\">2.7 Git Basics &#8211; Tips and Tricks<\/a><br \/><a title=\"Advance Git Aliases\" href=\"http:\/\/blog.blindgaenger.net\/advanced_git_aliases.html\" target=\"_blank\">More advanced aliases<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Once you have created an account on github, you will need to set it up so that you can use it with your linux account. First Step is to create a ssh private\/public keys for using in github. cd ~\/.ssh ssh-keygen -t rsa -C &#8216;salasiapro@yahoo.com&#8217; Now save this as id_rsa_github in the .ssh folder in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[44,49],"class_list":["post-550","post","type-post","status-publish","format-standard","hentry","category-full-tutorials","tag-git","tag-version-control"],"_links":{"self":[{"href":"https:\/\/blog.nssy.org\/index.php?rest_route=\/wp\/v2\/posts\/550","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.nssy.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.nssy.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.nssy.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.nssy.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=550"}],"version-history":[{"count":84,"href":"https:\/\/blog.nssy.org\/index.php?rest_route=\/wp\/v2\/posts\/550\/revisions"}],"predecessor-version":[{"id":1148,"href":"https:\/\/blog.nssy.org\/index.php?rest_route=\/wp\/v2\/posts\/550\/revisions\/1148"}],"wp:attachment":[{"href":"https:\/\/blog.nssy.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=550"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.nssy.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=550"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.nssy.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}