Showing posts with label Git. Show all posts
Showing posts with label Git. Show all posts

Friday, December 18, 2015

Managing Multiple Github Accounts from a single machine

Recently, I ran into a situation where I needed to manage multiple Github accounts from a single computer. I have two github account, one related to work and the other for my personal repositories.
It is a very simple combination of ssh and git config. Before I start explaining the steps for the same, let me clarify that the following steps are meant for LINUX/UNIX users.

1. Set up SSH keys


You will need to set up two different ssh keys for the two accounts.
$ ssh-keygen -t rsa -b 4096 -C "work.emailid"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/****/.ssh/id_rsa):       
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/anjana/.ssh/id_rsa.
Your public key has been saved in /home/anjana/.ssh/id_rsa.pub.

$ssh-keygen -t rsa -b 4096 -C "personal.emailid"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/****/.ssh/id_rsa): /home/****/.ssh/id_rsa_personal       
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/anjana/.ssh/id_rsa_personal.
Your public key has been saved in /home/anjana/.ssh/id_rsa_personal.pub.

Make sure that when prompted for the filename when generating the ssh keys for the second account, you give the appropriate filename.

2. Add the ssh key to your github account


> On your github account, Go to your Account Settings
> Click "SSH Keys" then "Add SSH key"
> Paste your key into the "Key" field and add a relevant title
> Click "Add key" then enter your Github password to confirm
> Repeat this step for your other account with the appropriate keys.

3. Create a ssh configuration file to manage the two separate keys

$ touch ~/.ssh/config
Add the following in your ~/.ssh/config file.
# Default GitHub
Host personal-github.com
HostName github.com
User git
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_personal

# Work GitHub
Host github.com
HostName github.com
User git
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa

Once you save this file, you need to configure your git repos on local accordingly.

4. Setup your repo


Replace "git@github.com" part in the remote origin of all your personal repositories to "git@personal-github.com"
And that's it. From now on, the appropriate user account will be used for pushing to these repositories.

Friday, December 12, 2014

Git Basics - A cheat sheet for your daily git needs.

This post is for anyone to refer to for their daily git needs. We will not be covering any advanced git concepts here.


Git is a distributed version control system.
Some basic terminologies:
Directory: A folder that contains multiple files.
Repository: A directory where Git has been initialized to start version controlling your files.

I have created an empty directory called gitBasics on my machine.
$ ls -a
.  ..

Let us initialize an empty git repository.
$ git init
Initialized empty Git repository in /Users/anjana/gitBasics/.git/
$ ls -a
.    ..   .git
As seen above, a hidden .git directory is created inside the the gitBasics, indicating that a repository has been initialized.

Next, lets see the current status of the directory as compared to the repository.
$ git status
On branch master

Initial commit

nothing to commit (create/copy files and use "git add" to track)

Now lets create a file filename.txt in the directory.
$ ls -a
.            ..           .git         filename.txt

Lets check the status again.
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add ..." to include in what will be committed)

 filename.txt

nothing added to commit but untracked files present (use "git add" to track)
git shows that an untracked file is present.

Lets add this file to the staged area.
$ git add filename.txt
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached ..." to unstage)

 new file:   filename.txt

Next, lets commit these changes.
$ git commit -m"Adding test file"
[master (root-commit) 4b8b52d] Adding test file
 Committer: Shankar 
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 1 file changed, 1 insertion(+)
 create mode 100644 filename.txt

At the time of commit, git tries to identify the author of the commit. In order to set this, use the following commands.
$ git config --global user.name "Anjana Shankar"
$ git config --global user.email "***@g***.com"

Now when you run git status, it says that the working directory is clean and there is nothing to commit.
$ git status
On branch master
nothing to commit, working directory clean

Next we have the git log command. This command prints the history of the repository.
$ git log
commit 4b8b52d4071a04c7f98436aae959ab9b10fec2ec
Author: Shankar 
Date:   Thu Dec 11 22:24:28 2014 +0530

    Adding test file

Now lets add the remote origin to our local repo.
$ git remote add origin git@github.com:*****/gitBasics.git

After the remote branch is added, we should push our code to remote git repo. This can be done as follows:
$git push -u origin master

In order to pull from remote branch, use the following command:
$git pull -u origin master

In order to see the differences between the current and the last committed version of code, use the following:
$ git diff HEAD
diff --git a/filename.txt b/filename.txt
index c9e358c..411cdda 100644
--- a/filename.txt
+++ b/filename.txt
@@ -1 +1 @@
-First File
+First File Modified

or you can simply use
$ git diff
diff --git a/filename.txt b/filename.txt
index c9e358c..411cdda 100644
--- a/filename.txt
+++ b/filename.txt
@@ -1 +1 @@
-First File
+First File Modified

A line prepended with '-' shows the deleted lines and a line prepended with '+' shows the added lines.

When we use the git add command, we stage the differences. Lets stage the differences first, and then understand how to unstage and reverse our changes to arrive at the last committed snapshot. I have created another file 'filename2.txt', Committed the file and then made some changes to it.
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

 modified:   filename2.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git add filename2.txt 
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD ..." to unstage)

 modified:   filename2.txt

To see the staged differences, use the following:
$ git diff --staged
diff --git a/filename2.txt b/filename2.txt
index f686acc..5701cbe 100644
--- a/filename2.txt
+++ b/filename2.txt
@@ -1 +1 @@
-Second File
+Second File Modified

You can unstage the files as follows:
$ git reset filename2.txt
Unstaged changes after reset:
M filename2.txt
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

 modified:   filename2.txt

no changes added to commit (use "git add" and/or "git commit -a")

After unstaging the changes can be undone as follows:
$ git checkout -- filename2.txt
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

Let's talk about branches now:
To create a new branch, use the following:
$ git branch newBranch

Use the following to switch branches
$ git checkout newBranch
Switched to branch 'newBranch'
$ git status
On branch newBranch
nothing to commit, working directory clean

I have modified 'filename2.txt' and pushed changes to this branch.
$ git log
commit 889ab1f0f42e7efd5818f68b30a42ced587db320
Author: Anjana Shankar <*****@gmail.com>
Date:   Fri Dec 12 10:14:05 2014 +0530

    Modified file on the branch

Now lets merge this branch to master. First we will have to switch back to master. Once you are on the master you can merge the branch.
$git checkout master
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git merge newBranch
Updating 7c4f3ad..889ab1f
Fast-forward
 filename2.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean
$git push
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:****/gitBasics.git
   7c4f3ad..889ab1f  master -> master

Finally as we are done with the branch, let's delete it.
$ git branch -d newBranch
Deleted branch newBranch (was 889ab1f).
$ git push origin --delete newBranch
To git@github.*****/gitBasics.git
 - [deleted]         newBranch

To see the remote branches available, use the following:
$ git branch -r
  origin/master

That's it in this post. Will try to cover a few advanced git concepts in my next posts.
Reference : Pro Git book

Monday, August 25, 2014

Splitting a git repository

Sometimes when you are starting with version control for your code, you dont know how big your repository is going to become. The decision whether to create a new repository for every module or to keep them all in one repository may be a difficult one.
When the modules are smaller, you would like to keep them all in one place. You can decide to move them in their own repository later. It took me some googling around to figure out how to split a git repo. This is fairly easy and this great blog post summarizes it very well. In this post, I am putting the lessons I learnt while splitting a git repo.

Please ensure that all your commits to the module are merged to master branch. The version logs of only the master branch would be preserved post the split.

Say, I have a git project called webservice.git. And it has the subdirectories service1/, service2/, service3/. Of these service1/ has grown large enough to be moved into its own repository.

Follow the following steps to move the folder service1/ into its own git repo, along with the logs of the master branch.

Step 1: Clone existing repo as desired repo:
$git clone --no-hardlinks git@gitserver:webservice.git service1

Step 2: Filter the branch and reset to exclude other files, so they can be pruned:
cd service1
$git filter-branch —subdirectory-filter service1 HEAD — —all
$git reset —hard
$git gc —aggressive
$git prune

Step 3: Create new empty repo on git server

Step 4: On the local machine, replace remote origin to point to new repo:
cd service1
$git remote rm origin
$git remote add origin git@gitserver:service1.git
$git push origin master