Now that I moved my blog to github-pages generated by octopress, using git is the only way to make progress. Rather than digressing about my experiences @migrating from wordpress to octopress- I would rather keep this post as my notes on
I find it interesting to learn by jumping-in rather than reading tons of volumes first. To get started you need to let git know that you are going to be setting a repository, this needs to happen in a particular directory- which contains stuff you want to manage. The command is:
git init . Initialized empty Git repository in /home/sarangb/learn-git/.git/
Once an empty git repo is initialized now the next step is to add some content for git to track. Lets start by adding a a script that fetches weather information (just for fun). Once I have the script the next step is to let git know about it.
git add *.sh git commit -m 'initial commit'
This will add all
sh files to git, this is two step process:
git addwill add the files to a staging area, more on that shortly
git commitwill commit files in git repo
Now that scripts have been added. Say you need to tweak the script and recommit the changes.
git add *.sh git commit -m "tweaked scripts"
git's perspective following stages occur:
- you started with an unmodified file, that’s the
unmodified stagein pic below
- you edited the scripts, git tracks filesystem for changes- that’s the
- you add file back- your intent is to eventually commit this file- but you haven’t done that yet. Thus
- on commit, git takes the
stagedchanges and commits them
Here is an image from git scm book, which explains how the files are tracked by git very well:
checking status of files
We have been creating and committing things. With projects you will generally have lot more files that just one/two files. And generally I keep an eye on what is modified and what is staged- to get a better picture of what things have changed and what I am committing. That’s where
git status comes into picture. For eg: this blog post hasn’t been committed yet so if i do
git status on my blog root directory I get:
$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: source/_posts/2015-05-16-notes-on-git.markdown no changes added to commit (use "git add" and/or "git commit -a")
Few things to note here:
- I am on
gittells me I have modified the file and can undo with
git checkoutcommand or stage with
Let’s add a few more files to our scripts directory to go with- namely the pic for git-lifecycle and a README.md Now we have two newly added files and a staged file, git would generate something like this:
$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: weather.sh Untracked files: (use "git add <file>..." to include in what will be committed) README.md lifecycle.png
tracking & staging files
Now that we know new files have to be added for tracking (and are staged) and modified files have to be added as well (for staging). However one of the things to note is
git add command stages file based on it’s contents and at that time.
$ git add --all $ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: README.md new file: lifecycle.png new file: weather.sh $ git commit -m "initial commit"
Let’s add a few things to
README.md and then stage the file. After staging file you realize you missed a few thingsi to note so tweak
README.md again and if you check
git status now you will see:
$ vim README.md // tweak a few things $ git add README.md // again tweak a few things $ vim README.md $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: README.md Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: README.md
You thought you already staged the file- which you did but that was at earlier point of time, contents have changed. Thing to note is git tracks/stages file based on contents, it internally generates SHA1 HASH.
The right way to fix things is to re-stage the
README.md file and then commit. Simplest way is to use command
git add --all, this will take care of adding/removing/stating files- but it does for everything. For managing what get’s staged you should setup
.gitingore file- so you can neglect generated/intermediate stuff that you don’t care about tracking.
not every file needs to be tracked in git repository. With C++ compilers generate tons of obj/archives and other temp files which we don’t care about to track. to let git know about what not to track you should. For eg: I was checking
Rakefile in blog root dir for pushing stuff to git as part of deploy. I have it open in
vim and made a few changes.
vim will create a temporary
Rakefile.swp, which I don’t care about, so is ideal candidate for ignoring. Here we go about ignoring things: :)
A quick check on my blog root directory says these files are set to be ignored
$ more .gitignore .bundle .DS_Store .sass-cache .gist-cache .pygments-cache _deploy public sass.old source.old source/_stash source/stylesheets/screen.css vendor node_modules Gemfile.lock
to add more to it i would
vim .\.gitingore and add
*.swp at the end and that’s it. You can add files/directories to
.gitignore and it should just work fine. Here are a few rules to keep in mind, source
The rules for the patterns you can put in the .gitignore file are as follows:
- Blank lines or lines starting with # are ignored.
- Standard glob patterns work.
- You can end patterns with a forward slash (/) to specify a directory.
- You can negate a pattern by starting it with an exclamation point (!).
Now that things have been set, it’s time start checking what changes are there before committing or staging. This is one of my most common workflow. I keep on staging and diffing files- love reviewing my own code :)
I just added
.gitignore, if i do
git diff command with no arguments it will tell me about all the files that have changed and the differences:
diff --git a/.gitignore b/.gitignore index f8a6236..8f85703 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ source/stylesheets/screen.css vendor node_modules Gemfile.lock +*.swp
git diff shows you diffs in what is in your working directory vs staging area- so it highlights changes that have been made since you last staged the file.
git diff takes in a lots of parameters but one of the most common is to see what you are committing and can be checked with
I have staged the
.gitignore file so this is what i will be committing
$ git add .gitignore $ git diff --staged diff --git a/.gitignore b/.gitignore index f8a6236..8f85703 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ source/stylesheets/screen.css vendor node_modules Gemfile.lock +*.swp
In case you want to see list of files that have been staged the command would be:
$ git diff --name-only --staged .gitignore Gemfile Rakefile
we have been committing changes all this while, this is the last in the various stages we saw earlier. You can directly issue
git commit command it will open an editor for you to enter comments,
vim for me. In case you have terse comments you can bypass this with
-m option with
git commit as we have done already.
$ git commit -m "updated .gitignore" [master 2e55fe1] updated .gitignore 1 file changed, 1 insertion(+)
git commit commits files that have been staged- at times with small changes two step process is a bit too much. I often make small changes and commit often. For this you can pass
-a flag with commit command, would have worked the same
$ git commit -am "updated .gitignore" [master 2e55fe1] updated .gitignore 1 file changed, 1 insertion(+)
This is a infrequent task and I would be careful with it. But comes in very handy when you have got un-neccessary files staged/committed. To remove the files from staging command would work.
git rm --cached README.md
I would ask you to refer git-scm book for details
statistics and history
I have been committing things as I wrote this post. To check the commit history
git log is the command:
$ git log commit 2e55fe118981f2ca4ee05d91c302b6f6441b8782 Author: sarangb <---@---.com> Date: Sat May 16 12:55:02 2015 -0700 updated .gitignore commit 39b672252189e9053b05e7cd606a80b5497fae15 Author: sarangb <---@---.com> Date: Sat May 16 11:53:00 2015 -0700 added drafts commit 41f41aaf3a0fee665ddaa8d1d8a09f5c8e13f4f5 Author: sarangb <---@---.com> Date: Sat May 16 11:34:06 2015 -0700
Or I can check in more details what was committed,
-p shows difference in each commit and i am limiting it to last commit with
1 as option
$ git log -p -1 commit 2e55fe118981f2ca4ee05d91c302b6f6441b8782 Author: sarangb <---@---.com> Date: Sat May 16 12:55:02 2015 -0700 updated .gitignore diff --git a/.gitignore b/.gitignore index f8a6236..8f85703 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ source/stylesheets/screen.css vendor node_modules Gemfile.lock +*.swp commit 39b672252189e9053b05e7cd606a80b5497fae15
For a brief summary I could alternatively have passed
--stat option. Or to generate a list of commits i have done so far with this blog- but in a bit less verbose and human readable form i would do:
$ git log --pretty=format:"%h - %an, %ad : %s" 2e55fe1 - sarangb, Sat May 16 12:55:02 2015 -0700 : updated .gitignore 39b6722 - sarangb, Sat May 16 11:53:00 2015 -0700 : added drafts 41f41aa - sarangb, Sat May 16 11:34:06 2015 -0700 : few more updates 9b002b5 - sarangb, Sat May 16 10:17:26 2015 -0700 : fixed build script 06a024f - sarangb, Sat May 16 10:09:43 2015 -0700 : updated read me for source ...
1. `%h` - will give you abbreviated commit hash 2. `%an` - will give you author-name 3. `%ad` - will give you the commit date-time 4. `%s` - subject or short description from commit message
For complete list of options visit this page
in the end of beginning
this is just scatching the surface of what git provides- there is still lot to explore:
- various tools and tweaks
- local server hosting, not sure if i will ever want to get into this
a few references
Well, this is most of the stuff I need to get started with git and octopress. Here are few resources that came in handy: