Friday, September 11, 2015

Useful commands for Github

Github is open source social code hosting plateform where we have public and private repositories (project). It manage repositories among multiple developer and can be sync from anywhere. Now, you can perform version control tasks (like pull,push, commit, revert,rebase changes) to repository either using github.com (UI interface) or using command line tool Git, which is popular these days.

You can use GitHub web interface for change tracking the repository but in case of simultaneously two user change same file, then changes will be overridden by one who check it last.Whereas, Git provide the local working directory with staging area and project history. Therefore, the person who push the code last will ask to pull the file before pushing code.

We will discuss step for creating public centralised reposiories in Github:

Step 1: Sign-up Github

You need to sign up by providing unique_name, email-id, password.

Step 2: Creating a New Repository using Command-line.
You can create a new repository using web interface, in this article we will discuss to create using command line.

Step 2.1: Installing and Configuring Git

I have installing Git using yum on CentOS machine as shown below. You can download and install Git according to system specification.
[code language="text"]
$ sudo yum install git
[/code]
In case you have error like "Unable to find remote helper for 'https'".Please follow below steps for installation:
[code language="text"]
#Install the package requirement for git
$ sudo yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
$ sudo yum install gcc perl-ExtUtils-MakeMaker
#remove the existing git
$sudo yum remove git
#Download the git source code
$ sudo wget https://www.kernel.org/pub/software/scm/git/git-2.0.4.tar.gz
$ sudo tar xzf git-2.0.4.tar.gz -C /opt/
$ sudo make prefix=/usr/local/git all
$ sudo make prefix=/usr/local/git install
#create git.sh file in /etc/profile
$ sudo vi /etc/profile.d/git.sh
# Add the file to git.sh file and then save and exit
export PATH=$PATH:/usr/local/git/bin
#source .bashrc
[/code]

Now, configuration set up Git using the below command line (specify user.name/user.email you specify in Github signup)
[code language="text"]
$ git config --global user.name "Your Name Here"
$ git config --global user.email "your_email@example.com"
[/code]
The configuration changes is stored in .gitconfig file in home directory or using list command as shown below.
[code language="text"]
$ cat ~/.gitconfig
$ git config --list
[/code]

Step 2.2 Generate SSH key
Github support protocol like git (not secure and push not possible), https (secure but require passwords/tokens) ,ssh (secure but required set up SSH key) for accessing the repository.
You can setup ssh (public key authentication) using command below. You can refer document for details.
[code language="text"]
#List all existing ssh keys
$ ls -al ~/.ssh
#Generate new ssh key
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Output:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/userName/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/userName/.ssh/id_rsa.
Your public key has been saved in /home/userName/.ssh/id_rsa.pub.
The key fingerprint is:
08:88:55:66:95:bd:bf:88:0e:dd:dd:46:77:f6:b9:b6 your_email@example.com
The key's randomart image is:
+--[ RSA 4096]----+
| |
| o |
| . . o . |
| + + o . |
| . + S . |
| . . . . |
| . . . o .|
| . o oooo|
| .o.++E=o|
+-----------------+
$ eval "$(ssh-agent -s)"

Output:
Agent pid 4648

$ ssh-add ~/.ssh/id_rsa
Identity added: /home/userName/.ssh/id_rsa (/home/userName/.ssh/id_rsa)
[/code]

Now, add the ssh key to GitHub account from https://github.com/settings/ssh as below

Screenshot

You can test the ssh configuration
[code language="text"]
$ ssh -T git@github.com
Output:
Hi userName! You've successfully authenticated, but GitHub does not provide shell access.
[/code]

Step 2.3 Adding New Repository

Create a New Repository on GitHub. Refer https://help.github.com/articles/create-a-repo/

Using below commands, we have created an repository/project on GitHub.
[code language="text"]
$ cd GitDemo
$ echo "# GitDemo" >> README.txt
$ git init
$ git add README.txt
$ git commit -m "first commit"
$ git remote add origin git@github.com:username/GitDemo.git
$ git push -u origin master
[/code]

OR push an existing repository from the command line

[code language="text"]
$ git remote add origin git@github.com:username/GitDemo.git
$ git push -u origin master
[/code]

OR You can add a empty repostory on github using below command

[code language="text"]
$ curl -u 'xxxx' https://api.github.com/user/repos -d "{\"name\":\"GitDemo\"}"
Output:
Enter host password for user 'user.name':
{
"id": 41167919,
"name": "GitDemo",
"full_name": "user.name/GitDemo",
"owner": {
"login": "user.name",
"id": 33333,
"avatar_url": "https://avatars.githubusercontent.com/u/3756379?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/xxxx",
[...snipp----]
"default_branch": "master",
"permissions": {
"admin": true,
"push": true,
"pull": true
},
[..snipp...]
[/code]

Now, we will dicuss the commands to change tracking tasks on repository.

Step 1.1 Fetching the local working directory from GitHub
Using clone command you can create a working copy of the repository (snapshot of master branch code at particular time) which you can use for development.
[code language="text"]
# clone a existing repository and point to master branch
$ git clone git@github.com:userName/GitDemo.git
# Navigate to your working directory
$ cd GitDemo
# Now, you can checkout to branch you need to work on
$ git checkout branch1
[/code]

Step 1.2 See changes between commits and working tree
Using diff command, you can see changes made in working tree from GitHub files or between 2 commits.
[code language="text"]
# Show difference between working directory and GitHub files
$ git diff

Output:
diff --git a/README.txt b/README.txt
index 0e8a4bf..1a117eb 100644
--- a/README.txt
+++ b/README.txt
@@ -1 +1,2 @@
Customer portfolio will show now its age amd name.
+I am now in testing phase
diff --git a/src/java/Customer.java b/src/java/Customer.java
index 93f7581..5d50a75 100644
--- a/src/java/Customer.java
+++ b/src/java/Customer.java
@@ -1,2 +1,10 @@
+public class Customer{
+String custName="";
+String age;
+public void setCustName(String custName){
+ this.custName=custName;
+}
+}
[/code]

Step 1.3 Find out changes made in working directory (Staging Area)

After you make changes in working directory, it is possible to split and group related file together using Staging Area. Using status command you can view the state of working and staging area. Therefore, it will show modified/untracked files in output as shown below:

[code language="text"]
$ git status
Output:
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: README.txt
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# src/
no changes added to commit (use "git add" and/or "git commit -a")
[/code]
Note: Files that you want to ignore like .exe,.class etc should be recorder in .gitignore file in root of working directory.Then it will not appear in status command as well.

Step 1.4 Commit code to local Git project history.

Before you commit your changes,you want to group or split related file together.

1.4(a) Using add command, you tell git to add all changes to this file in next commit.Note:No changes are recorded using this command.
[code language="text"]
$ git add <file_name>
[/code]

After you are satisfied with staged snapshot (using git status command) you commit it.

1.4(b) Using commit command, you tell git to record changes to local project history
[code language="text"]
$ git commit -m "comments"
[/code]

Step 1.5 Push changes to remote repository GitHub
Once the changes are commited in local working repository, you can push the changes to GitHub (master branch/master)
[code language="text"]
# Push the code changes to Master branch (not adviceable)
$ git push origin master
#Push code changes to branch name "branch1"
$ git push origin branch1
[/code]

Step 1.6 Viewing old commits
You can view all previous commit made in branch or master.

[code language="text"]
$ git log --oneline

Output:
b0a6b8f Revert "Change to revert"
17ebb40 Change to revert
2739150 Customer.java changes
3c46b93 Merge pull request #1 from poojagpta/branch2
7bc8863 Add new file
090c318 first commit
[/code]

Step 1.7 Revert a commit pushed to remote repository(GitHub)
There are many ways to correct the mistake, simply you can change files,commit it and pushed it again to remote.But if there are bunch of bad committed files, you can use following commands.

a) Revert command: Use this command to revert to a commitId (use Step 1.5 to find commitId) and then push to remote as shown below.
Note: Revert is logged into the history also. So can be view using log command as shown in Step 1.5.

[code language="text"]
$ git revert 17ebb40

Output: Git will ask to select the files to be reveretd from the list of files committed as shown:
Revert "Change to revert"

This reverts commit 17ebb40a5c569610c37a10c412e6e1bcdbef0e71.

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch branch1
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
modified: NewFile
modified: README.txt
deleted: branchFiletoRevert
# modified: src/java/Customer.java

After you select the file to be revered save it. It will show up message:
Finished one revert.
[branch1 b0a6b8f] Revert "Change to revert"
4 files changed, 1 insertions(+), 11 deletions(-)
delete mode 100644 branchFiletoRevert
[/code]

Now, we need to push the revert changes to remote repository Github
[code language="text"]
$ git push origin branch1

Counting objects: 11, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 968 bytes, done.
Total 7 (delta 0), reused 0 (delta 0)
To git@github.com:poojagpta/GitDemo.git
17ebb40..b0a6b8f branch1 -> branch1
[/code]

b) Use reset command: Using reset command, you can rollback to previous remote commit repository as shown below, but it will delete the project history. Note: Don't use it in master/remote repository.Prefer to use it in local repository only.
[code language="text"]
# Move the local project history to one commit before
$ git reset HEAD^
$ git push origin branch1 -f

Output:
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:poojagpta/GitDemo.git
+ bb19386...7c0e42c branch1 -> branch1 (forced update)

# If you want to remove the grouping of file you did before commit, you can use it
$ git reset
[/code]

Branching and Merging

Creating a new branch in GitHub
In GitHub, new branches can be created using below commands:
[code langauge="text"]
# create a local branch
$ git checkout -b dev
Output:
Switched to a new branch 'dev'

#Local commit to project history (skip staging area by using -a option)
$ git commit -a -m "Fist Commit in dev"
#Push changes to remote repository
$git push origin dev

Output:
Counting objects: 12, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (9/9), 1.02 KiB, done.
Total 9 (delta 0), reused 0 (delta 0)
To git@github.com:poojagpta/GitDemo.git
* [new branch] dev -> dev
[/code]

Listing all branches in git:
[code language="text"]
$ git branch -a
[/code]

Deleting branch in GitHub

[code language="text"]
$ git branch -rd origin/dev -- deletes remote branch
$ git branch -D dev --deletes local branch
[/code]

Create tags in branch
Tagging branches for release
[code language="text"]
$ git tag 2.0-xx3 -m "Release candidate 2.0-xx3"
$ git push origin --tags ---push tag to repo
[/code]

Rebase branch in Github
We need to rebase our dev branch to master branch.

[code language="text"]
$ git remote -v
origin git@github.com:poojagpta/GitDemo.git (fetch)
origin git@github.com:poojagpta/GitDemo.git (push)

#fetching the latest code from the master branch
$ git fetch origin

#Rebase dev branch with master changes
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: Fist Commit in dev
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging README.txt
CONFLICT (content): Merge conflict in README.txt
Failed to merge in the changes.
Patch failed at 0001 Fist Commit in dev

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

#Merge the code using the tool i have use mergetool meld to view the difference
$ git mergetool -t meld

#Then continue merge
$ git merge --continue

#finally push changes to github
$ git push origin dev -f
[/code]

Fork a Repository
Fork is creating a copy of the repository, in which you can experient without affecting parent repo. In many open source project, you don't have push rights so you can contribute by forking the project to your repositories and then making changes in it and then sending them pull request to review and merge.

Forking
GitHub provide a good tutorial on how to fork a repo. But for summary, there is button 'fork' on top right side of repository you want to fork as shown below.
forkButton

After pressing fork button, the repository can be viewed in your own github account.

No comments:

Post a Comment