Git In Hindsight

A 20/20 on commands found in the Git Cookbook

Git

Is a DISTRIBUTED source code control system that has gained popularity particularly with the open-source community as it allows one to have local source code repositories sharing changesets with other remote sites. With git, its possible to have a mesh of remote sites where one can either pull changes down from the remote sites or publish local changes to these remote repositories.

You can take a look at https://git-scm.com/book/en/v2/Getting-Started-Git-Basics to understand the Git internals, but there are a couple of key concepts to know when using Git.

When you clone another Git repository, the full repository with all the change sets will be downloaded and stored in your local working directory – generally .git/ . This hidden folder will contain a complete duplicate of the remote repository allowing you to look at changes that have happened.

You can also commit your changes to this local repository. Committing changes to your local repository is a multi-step process.

First you must stage your changes. Basically this tells git that you are planning to commit the files. You do this by performing a git add and specifying a directory, a filename or some combination of those. When you add a file, git places a copy of that file in its staging area. If you were to edit the file immediately after adding it, git wouldn’t see those changes. It only grabs the file contents at the time of the add. That’s okay though since if you edit the file after adding it, you can still re-add the file to get Git to update the staging area with the file’s most recent data. You can make many calls using git add to add more files to the staging area.

Additionally prior to committing your files in the staging area to the local repository, you can throw away those changes easily.

Once you’ve decided that you have all the files that you want in your commit, you can execute a git commit to tell git to place them into the local repo.  Once there, you can make further changes, create branches etc.

When you’re ready to push your changes to another repository, you can use the git push command to push data from your local git repository to the remote repository. Often you will have a single remote repository referred to as the origin which you can push your changes into.

Additionally there will most likely be changes occurring in the remote repository done by other contributors. You can get these changes using git pull to pull down those changes into your local repository and also place them into your local working area.

Git References:

  • http://eagain.net/articles/git-for-computer-scientists/
  • http://try.github.io/
  • http://cworth.org/hgbook-git/tour/
  • http://jonas.nitro.dk/git/quick-reference.html
  • http://stevebennett.me/2012/02/24/10-things-i-hate-about-git/
  • https://github.com/blog/2019-how-to-undo-almost-anything-with-git

 

Questions And Answers

Branch Management
Q: How do I create a branch off the master branch both locally and remotely?
A: First create your branch locally via git checkout -b desiredBranchName. Then create the branch remotely via git push -u origin desiredBranchName. There is some discussion of this topic on Stack Overflow here ( http://stackoverflow.com/questions/1519006/how-do-you-create-a-remote-git-branch )

 

Q: How do I merge changes from a branch (e.g. desiredBranchToMerge) to master?
A: First, make sure you are working in your master branch (e.g. git checkout master). Then simply issue the command git merge desiredBranchToMerge. e.g.

$ git checkout master
$ git pull origin # get the latest changes
$ git merge --no-commit desiredBranchToMerge # the --no-commit will not commit the changes allowing you to modify if needed

This will merge the branch and commit those changes to the local repo.

To uncheckout a particular file

$ git reset {filename}
$ git checkout -- {filename} # to throw away changes to file

To push the changes to origin,

$ git push origin

To throw away the changes and resync to what is stored on associated origin git repository

$ git reset --hard origin/master

Q: How do I determine who created a specific branch?
A:  Use the following to get a table

git for-each-ref --format='%(committerdate) %09 %(authorname) %09 %(refname)' | sort -k5n -k2M -k3n -k4n

Q: How do I delete a branch both locally and remotely?
A: First make sure you are working in say the master branch and then delete your branch locally via git branch -d branchToDelete. Then delete the branch remotely via git push origin :branchToDelete. There is some discussion of this topic on Stack Overflow here.
Identifying Changes

Q: I have created a branch in git to do some body of work. Now what I would like to do is to produce a diff file that identifies all of the changes I have made on that branch so that I can give it to someone without using git. How can I produce that diff file?
A: While on the master branch, issue the following command : git diff HEAD…branch > diffFile. Yes, that is correct three dots between HEAD and the branch name. e.g. git diff HEAD…jsr330spike > ~/jsr330spikechanges.txt
Hmmm, I usually just do git diff ..HEAD and it works fine. e.g. git diff master..HEAD – David Van Couvering. Thanks David, in my testing your approach works fine as well, without needing the step to first checkout master. Your approach is more efficient, unless of course you need to be doing work on master for some other reason.

Q: How do I show the files changed by a commit?
A:

git show --name-only

File Recovery
Q: I have deleted a file and committed that change to git, maybe even going to so far as to push that change to our central repository. Now I realize I still need that file, how do I get it back?
A: First, run the git command : git log –diff-filter=D –summary. This will give you a listing of all of the commits where a file has been deleted. Find the hash that identifies the commit where that file was deleted in that output. Lets say that hash is 37e3ce152783913278c427eb9a294cbca630632, and the relative path to that filename is libraries/someservice/somefile. Then issue the following command to recover that deleted file : git checkout 37e3ce152783913278c427eb9a294cbca630632~1 libraries/someservice/somefile. There may alternative solutions to this. An article on Stack Overflow that describes this and other solutions can be found here.

Q: How do I get only part of the repo
A: Assuming that you only want the most recent change for each file in the git repo, you can do something like:

$ git clone --depth=1

Q: How do I turn a depth=1 repo to normal
A: Right, unless you reset your local repo, it will not have the full history of the remote repo. To get it
to fetch the full history from the remote git repo:

$ git fetch --unshallow

Q: How do I change the remote.origin.url for a GIT repo
A: So you have a couple of ways to do this. 1 is that you can change the ‘origin’ repo to be a different url

$ git remote set-url origin git@gitlab.mycompany.com:my-repo/my-repo.git

On the other hand, if you want to also keep your original repo as the origin, you can add another url e.g.

$ git remote add alternate-remote git@gitlab.mycompany.com:my-repo/my-repo.git
# Now to push to this 'alternate-remote' instead of the origin, you do
$ git push -u alternate-remote my-branch 

Q: How do I see the remote.origin.url for a GIT repo
A: you can do 2 ways:

$ git remote -v
$ git config --get remote.origin.url