How to Interactively discard selected changes in git

GIT is offering us the way to discard selected changes interactively. Here is how you will do it,

To checkout or discard selected changes from all modified files

git checkout -p  

If you want to checkout or discard selected changes from specific file, give that file as an argument

git checkout -p  file_name

As per this command git will break down the file into chunks called hunks. After you execute this command, you will be prompted with following question with several options to choose.

Discard this hunk from worktree [y,n,q,a,d,/,e,?]?

Here is the description of each option,

y – discard this hunk from worktree
n – do not discard this hunk from worktree
q – quit; do not discard this hunk nor any of the remaining ones
a – discard this hunk and all later hunks in the file
d – do not discard this hunk nor any of the later hunks in the file
g – select a hunk to go to
/ – search for a hunk matching the given regex
j – leave this hunk undecided, see next undecided hunk
J – leave this hunk undecided, see next hunk
k – leave this hunk undecided, see previous undecided hunk
K – leave this hunk undecided, see previous hunk
s – split the current hunk into smaller hunks
e – manually edit the current hunk
? – print help

You can also unstage the selected changes from all staged files or from specific file.

To unstage selected changes from all staged files use following command

git reset HEAD -p

To unstage changes from specific file give that file as an argument.

git reset HEAD -p  file_name

Here also you will be prompted to choose any one of the option to unstage hunk.

 

GIT Tips

List Contributed Users

We can list the user who contributed in git using command git log.  Here is the way to get,

And you can check users who contributed using following command

Enable Debugging

You can see curl debug message while push, pull and clone if you set the environment variable GIT_CURL_VERBOSE to 1

$ export GIT_CURL_VERBOSE=1

Set this variable before you push or pull or clone. You would be able to see debug message

List History Of Operations

The following command can be useful to list all history of operations performed using git

 

Stage all modified files in git

Stage all modified files using single command.

How to edit or change commit history using git rebase

Do you ever wonder about rewriting git commit history. Here is how you can do. One great advantage we get with git version control system is that, we can edit or rewrite the history of commits. Some times may be you want to publish the different commit history or for some reason you may want to edit the few chunks for commit history.

There are different ways to edit the history of commits. There is one quick way to edit the very last commit or HEAD. Using following command

If you want to edit selected commits in the history, you can do it using feature called rebasing in git. Rebasing is a great feature in git. Other than process called merging  we can use rebasing to merge different branches in different way other than usual git merge. One of the advantage is we can rewrite the history to make sure commit history looks like the way you want.

We have to use interactive rebasing to edit the commit history, using the following command

where we specify the commit  which is parent of the commit  from which you want to edit the commit history

Lets say I chosen the commit from where I want to edit the history, I would type the following command

If you perform above command, you wold see the following content in the default editor,

The above content is self explanatory, if you want to remove commits just remove corresponding commit line. if you want to abort interactive rebase any time use git rebase –abort. You should notice that your last commit is at bottom. These commits from chronological from top to bottom.

If you chose to edit the selected commits, let’s say want to change author, you have to replace the word pick with word edit for that corresponding commits and quit the editor by saving. Then you will stop at the first commit, you can change the author using following command

Like wise you can change the commit message as well. Of course you can also change the content of files to commit

and then to continue rewriting history using following command,

You have to  repeat these steps for each commit that you change the  word pick to edit. Git will stop to let you amend the commit. Once you are finished with specific commit, you can proceed further by using rebase command using command line argument –continue. 

Once you finished with rebase, you may see the following message

If you get conflicts, you have to resolve them in the way you resolve for merging process. Once you resolved the conflicts by removing conflict markers(>>>>>> ======= <<<<<<<). Use to git add  to mark them resolved. Then continue to rebase using command

 

WARNING:

Beware of rebase,  you may corrupt the commit history  of your team members and it may leads to confusion.

If you are learning don’t try to experiment it on real repository. Instead you create the dummy repo and get hands on experience.

You may produce merge conflicts sometimes, you may have to resolve to proceed the rebase

Want to read more?

References:

[1] https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History

[2] https://git-scm.com/book/en/v2/Git-Branching-Rebasing

 

GIT – How to push code to multiple remotes simultaneously

Well, if you are looking for the way to push multiple remotes at the same time, you might be aware of git well enough. We call remote repositories as remotes in git. Pushing changes to remotes would be the part of usualy development cycle.

Some times you may need to push changes to  multiple remotes like github and bitbucket etc. To do so, you can follow below given instructions.

List your existing remotes

You can list all avaible remotes using following command

$ git remote -v

If you don’t have already any(other) remote configured. You can do by using git remote

$ git remote add  remote_name  remote_url

Example:
git remote add github   http://github.com/path/to/repo

Usually, we push changes by addressing remote name by default origin something like git push origin. You can configure group multiple remotes and give it a name. So you push to all those remotes by referring that name.

You can add multiple remotes by using either git remote or git config commands or even you can edit config file.

As git can group multiple remotes. You can follow any of the following way to configure multiple remotes to push simultaneously(no need  all)

Add remotes using git remote

You can set multiple remote urls to single remote using git remote

If you don’t have remote named all already create it using git remote add then use git remote set-url –add to add  new url to existing remote  

git remote set-url all –push –add <remote url>
git remote set-url all  –push –add <another repo remote url>
git remote set-url  –add  all   <another>

You can cross check added new remotes using git remote -v

(OR)

Group multiple remotes using git config

Command git config is used to configure git parameters. It will edit the .git/config file as per given input

git config –add remote.all.url  http://domain.com/repo.git
git config –add remote.all.url  ssh://user@host/repos/repo.git

Note with out –add option command will replace existing remote url. You can verify updated conf  at .git/config

(OR)

Edit file .git/config  to add remote and multiple remote urls if you are aware of configuration format.

Now you can push multiple remotes simultaneously by referring remote name which is having multiple remote urls assigned.

git push all master

You can always push to multiple remote repos with out grouping them using formal bash syntax

git push server master && git push github master 

How to Interactively discard selected changes in git

Question: How to interactively discard the selected changes in git ?
Answer:
git is offering us the way to discard selected changes interactively. Here is how you will do it,

To checkout or discard selected changes from all modified files

git checkout -p  

If you want to checkout or discard selected changes from specific file, give that file as an argument

git checkout -p  file_name

As per this command git will break down the file into chunks called hunks. After you execute this command, you will be prompted with following question with several options to choose.

Discard this hunk from worktree [y,n,q,a,d,/,e,?]?

Here is the description of each option,

y – discard this hunk from worktree
n – do not discard this hunk from worktree
q – quit; do not discard this hunk nor any of the remaining ones
a – discard this hunk and all later hunks in the file
d – do not discard this hunk nor any of the later hunks in the file
g – select a hunk to go to
/ – search for a hunk matching the given regex
j – leave this hunk undecided, see next undecided hunk
J – leave this hunk undecided, see next hunk
k – leave this hunk undecided, see previous undecided hunk
K – leave this hunk undecided, see previous hunk
s – split the current hunk into smaller hunks
e – manually edit the current hunk
? – print help

You can also unstage the selected changes from all staged files or from specific file.

To unstage selected changes from all staged files use following command

git reset HEAD -p

To unstage changes from specific file give that file as an argument.

git reset HEAD -p  file_name

Here also you will be prompted to choose any one of the option to unstage hunk.

 

GIT: How to push code to repository on remote ssh server

You can push to  git repository which is on remote ssh server using git. You can configure remote repository as a git remote to be able access quickly using remote(short) name.

To be able to pull and push changes to repository on remote ssh server you have to specify it using any one of the following URL format.

For Instance, if repository is located at  /opt/project, URL would be

ssh://user@server/opt/project

You can push changes using following syntax

git push ssh://user@server/opt/project  master

or

git push server master

Where,

server is remote configured using git remote  command
master is the branch to push

or, it can also be specified in scp-like syntax

For Instance, if repository is located at /opt/project, URL would be

user@server:/opt/project

You can push changes using following syntax

git push user@server:/opt/project  master

or

git push server master

Where,

server is remote configured using git remote  command
master is the branch to push

When you push changes, you will be prompted for the password. You can configure ssh keys to bypass password authentication when you push changes.

How to fix GIT object file is empty error

 

You might have encountered this weird git object file is empty  error when your machine/laptop ran out of power while you are working with git, boom 💣

In this case, you can recover your repository simply by cloning new from remote repository if you don’t have much changes locally. Else, you can follow below mentioned procedure to recover your local repository.

If you try to commit your local/stated changes.

When repository is corrupted you would see error something like below when you try to commit changes

Take a backup of directory .git

$ cp  -a  .git .git-old

Run, git fsck to get corrupted files/objects. i.e, git fsck –full

Now, our job is remove all empty files reported by git fsck

Once you delete all empty files reported by git fsck. git fsck will start showing up missing blob.

If you are lucky enough your problem will be solved with the following step.

NOTE: dangling blobs shown by git fsck are not error

If you delete all empty files, then run git fsck. If it is reporting “missing blob” then look checkout git reflog. It should show “fatal: bad object HEAD”, else probably your problem will be solved with just git reset

$ git reset

If your problem is not solved and git reflog is showing up “fatal: bad object HEAD”. Run the following command to fix broken HEAD

Now, update the HEAD with parent of last commit

Now, run git fsck. If you see error something like invalid sha1 pointer in cache-tree . You can fix it by removing .git/index file and resetting repo using git reset

Check the status and then commit if you required and problem is solved.

 

References:

[1] http://stackoverflow.com/questions/11706215/how-to-fix-git-error-object-file-is-empty

 

How to see stashed changes using git stash

The command git stash is used to stash the changes in a dirty working directory away.

You can list all stashed change using the command  git stash list,

Every time you stash your working directory, git will save the state of working directory into somethine which mantins history of stash tree. Every time you stash your changes it will be save as a kind of commit in stash tree. All stashed changes are stacked in the order with serial or reference. stash@{0} is the first or top most or recent stash. Every time if you want to refer a particular stash you have to use the it’s reference id something like stash@{3}, stash@{5}… etc

Think of each stash as a separate  commit. These commits are stored and stacked differently and not overlapped with conventional git commit history 

A stash is represented as a commit whose tree records the state of the working directory, and its first parent is the commit at HEAD when the stash was created.

The following command can be used to extract diff of stashed change againest any other stash or commit or branch or HEAD.

  • git stash show
  • git show
  • git diff
  • git difftool

Let’s see, how we can use each of the above mentioned commands.

Command git stash show

The simple command git stash show  gives very brief summary of changes of file, but will not show the diff of changes against current HEAD. Something like,

Something like below

Some times this is not so useful. You may want to see the difference against  current HEAD or any specific commit or current directory.

If you use git stash show along with option -p, It will show all changes.

 

Check diff against selected stash.

Command git show

The command git-show  is used to see  various types of objects.

The command git-show is not only used to visualize  stash changes, but also used to see one or more objects like blobs, trees, tags and commits. For more information check git-show

Synopsis: 


To see top most stash difference against  HEAD:


To get diff of of selected stash against HEAD:


See selected complete whole file as if stash is applied  from selected stash:

Where,

stash@{0} is the reference of stash. I could be any one of stash@{0}, stash@{1}, stash@{2}… etc.

<file_name>  is the name of the file relative to project/git repository

Command git diff 

The command git-diff  is also one of common command which is used to show changes between commits, commit and working tree, etc.

By default, git diff will show the diff of selected stash against(modified files) current state of repository unless other stash  reference or commit is specified.


To get difference between top most stash stash@{0} and master branch:


Only display the names of file not diff of changes:


See the diff between selected stashes for a selected file:

 

Command git difftool

The command git-difftool can also be used to find diff between selected stash and selected commit or branch or stash

See the difference between latest two stashes:

 

 

Summary: 

Commands which are  useful to extract the diff from selected stash git stash show, git show,  git diff, git difftool . 

See difference using command git stash show,

See the changes in the stash using command git show,

See the difference between latest stash and selected commit using command git diff,

 

References:

[1] https://git-scm.com/docs/git-show
[2] https://git-scm.com/docs/git-stash

 

About SCM Source Code Managment System

GIT The Source Code Management System(SCM)

Many people uses version control system but they have on idea why they are using it, as the team is using, they will also use it get work done.

Why do we need version control system? Here are the few requirements, from where the SCM idea comes.

See the project directory with out version control system. Project directory with no SCM

When ever you think to have snap shot of your source code for that particular moment, then you have to copy your source code directory by naming it according to that moment. Like wise you may do it with tarballs to save memory. Its horrible….not?, you will end up with endless tarballs or directories as per the project.

Just think, your other developer asked about release code that you did on some x day. Then you have to send him whole project directory if every file got changed and he is not having those changes. You did some performance fixes, it takes 70% refactoring, and it’s an experiment then you should keep your project directory backup, before you starting doing these performance fixes. And also you need to have directory/tarball when you completed with your changes, because you may not undo your 70% of changes if you want the last stable code that you have before 70% of refactoring for performance. If these changes are not stable and will take long time to get them stable, in such a case you will replace your production with the directory that you copied before you did performance fixes.

If we go like this, you will end up with whole hard disk with your single project. Even though, you will not dare to find some directory(If you think of directory as snap shot or save point).

Now come to team collaboration, there is no pretty much better way to communicate with the team with code changes up to dated as per time with out SCM. Some times your team will need to wait for the fixes those are being implemented by others, to get source code. In this case one person can work faster than the 10 persons. Because every body else will end up by doing nothing other than taking/giving changed files looking at differences, asking others about changes and finally preparing single file by combining working changes.

All this story about when we don’t have source code management system. Now imagine the development with out SCM.

Thats why the version control system comes into picture.

Version control, also known as revision control, source control management, is the management of changes to files, programs and other information. Version control system allows us to track the incremental changes in files or content. Provides the ability for many developers to work on single file or project concurrently.

The project directory with SCM (GIT) Project With SCM

There are lot of SCM softwares out side including open source and commercial. Here are few….

  • CVS
  • SVN
  • BitKeeper
  • GIT
  • Mercurial

There are lot of softwares available other than I have mentioned, you can find them at list of version control systems

We can classify the version control systems based on their model. That is centralized and distributed. You may call centralized as client server model. As there are many version control systems no one meet all requirements at all.

Here are few characteristics of version control systems, which will vary around each version control system.

  • User interface
  • Performance
  • Memory management
  • Learning cure
  • Maintenance

Apart from them there are two other things to consider, Open source/Proprietary Centralized/Distributed

Lets have a look at GIT. GIT is a distributed revision control system which is especially designed for speed. It was designed by Linus Torvalds in early 2005. It was designed to manage kernel source code, and for the BitKeeper
replacement. Linux kernel was managing with BitKeeper before GIT was invented. It’s initial release was 7 April 2005. GIT is really helpful for open source projects where it supports merges much better than any other SCM.

Here is how GIT distributed(decentralized) model would look like.GIT decentralized model

And centralized model would look like:GIT centralized model

In centralized model whole git history is resides in only central repository. We need to have connected via network to commit our changes unlike git(distributed). It required additional maintenance and need to take source code backups to regret central repository from any hardware failure of so.

First time with GIT:

Every git repository is nothing but a directory either on server or locally in your machine.

Creating the GIT repository is very simple, go to the directory that you would like make it as your git repository. To make sure you are in that directory justify it by the command pwd.

figure 1

Here I would like to make my PROJECT directory as GIT repository. It’s simple, with the following command.

figure 2

One more thing, if your directory is git repository you would have .git inside.

figure 3

GIT use to track changes and all with this directory.

We do save our changes with in commit. You may think each commit as one save point. You can go back to that history or save point when ever you want. You can tag commits with your version numbers. That is like v1.0, v2.0, v3.2,…. so on. You may call commit as revision or version as well.

As GIT uses a unique SHA1 to identify the commit. So each revision can be described by 40 characters hexadecimal string. Instead of mentioning this long commit hash into the releases and executables git users tag that specific commit with version number. So we can identify and get that specific source from the incremental git source tree for that version.

For each commit we will give some descriptive message we will call that as commit message. Here is the commit look like, it’s from git source.

figure 4

Here we see four things, commit, author, date and commit message. In each commit git stores the author name and his email. So we need to configure git to take our name and email and other settings if required to have them in commits we do. There are global and repository wide settings/options.

Here is how you can configure settings

figure 5

If you use –global you will have global settings configured. Those will take affect over each repository. Repository settings have more precedence than global. You need to take –global off from the command to have repository wide options configured. Make sure you are in side repository to configure repository wide options. You don’t need to be in repository to set global options.

To view git configured settings, try the command

$ git config –list

figure 6

If you use command line option/argument –global that will show all configured global level options.

$ git config –list –global

There are many more options to customize git behavior. But we very few options often.

GIT First Commit:

There are three states in the git commit procedure. Your file resides in any of the following state, those are

  • Modified
  • Staged
  • Commited

Modified means you have changed or added file and have not stored in git database. Staged means you have marked changes in current version to go into next snap shot, that is commit. Committed means, you have saved your modifications into database. The middle state is optional and it is to avoid accidental commits. We can skip this if required but it’s not recommended.

Adding files and modifying committed files comes under modified state. If you don’t add your new files those will be treated as untracked files.

To add or stage files use the following command.

git add is the multi purpose command we use that to both track new files and to stage new files.

Now add first file into our repository

Create a new file

GIT won’t track the changes of newly added files unless we say. That is unless we track that file. Newly added files are untracked, git won’t show modifications to those files.

Command git status will show us the status inside the repository. It will give the idea about three things, Untracked files, Modified file (Modified files are tracked files ) * Staged files

Here is screen shot where new file will be shown untracked.

Current Status

Now have this file added into the git database.

Add Modified File(s)

The status after we added that file,

Commit

In the above screen shot command git add made the given file stated. The files which are below the secion #changes to be committed are staged files. It’s second state as we discussed. Now we have to commit the staged file. The git commit will do that. It will take the argument -m along with the commit message. If we don’t give commit message with -m we will have editor open to enter commit message.

Finally, to see our history or previous commits we have the command