Git Reminders

Sorry about the mess, I've just been adding notes as I come accross them. I need to clean up this page.

Good article on resolving merge conflicts:

https://help.github.com/articles/resolving-a-merge-conflict-from-the-command-line/

I never realized that it was as easy as fixing the file with conflicts (and removing the merge markers that git put there), and then doing a git add.

 

handling merge conflicts

http://css-tricks.com/deal-merge-conflicts-git/

The most interesting point in this post is that after you clean up the files that are conflicted, you need to do 'git add filename' to tell git that you have resolved the conflict.

 

Quick tip: on github, press 'm' to pull up the markdown reference cheat sheet

 

 

If you remove a bunch of files from the project w/o using git to remove them. Then later you want to remove them from git. Do the following command:

 

git add -u

 

 

 

 

To see which of your local branches track to remote branches

 

git remote show origin

 

 

 

DELETE A BRANCH, BOTH LOCALLY AND FROM GIT LAB, note that to remove a branch from gitlab, you don't need to have it local

 

#remove it locally
git branch -D branchname

#remove it from gitlab (use colon before branchname)
git push origin :branchname

 

 

 

WHEN YOU WANT TO CHECKOUT A REMOTE BRANCH THAT SOMEONE ELSE CREATED

If someone else pushed a branch called 'somebranch' to the server and your local box doesn't know about it yet, DONT DO THIS:

git fetch origin somebranch  #DONT DO THIS!!!! 

 because this will pull all of the files from somebranch into your working directory for whatever branch you are currently on. And then you'll have a bunch of uncommited changes in your current branch. Instead do this:

git fetch origin && git checkout somebranch

This will allow your local box to be aware of 'somebranch' and you can then switch to it without messing up your current branch.

 

 

FAST FORWARD MERGE - when you make a new branch, add some commits to the new branch, and merge back to the original branch AND the original did not change since the new branch was created (it's a nice, clean merge and it basicaly moves the original branche's pointer to the same commit as the new branch, hence the term fast forward). If the original branch had changed while we were working on the new branch, then we'd have to do a 3-WAY MERGE. In a 3-way merge, the original branch will create a new comit that has two parent commits (one of the parent commits will be where the original branch is at the time of the merge, the other parent commit will be the commit that the new branch is at when you merge)

 

Example of a 3-Way merge.

(commit)<--(commit)<--(commit)<--(commit)<-----(commit) original branch
\ /
(commit)<----(commit) new branch

Note that the original branch had a new commit after the new branch was created.
Also note that, as a result of the merge, the original branch's HEAD commit has 2 parents (pointing to two commits).

 

 

 

a CLEAN WORKING DIRECTORY - when ther are no uncomitted changes and your working directory is the same as HEAD.

 

HEAD refers (points to) the most recent commit of your current branch, so in a distributed system developers may have different heads (one might be working on one branch, while another works on a different branch).

 

GIT vs SVN - SVN keeps track of changes to each file in your project, GIT keeps track of commits (I think I need to expand on this)

 

UNDOING CHANGES:

Let's say that after you do a commit you realize that you forgot to include a file with the commit. You can roll it back like this:

 

git reset HEAD~1
# never do this if you have already pushed the commit that you
# are resetting!!!!!

This will move the files with the commit back to staging, then you can stage the file you forgot to add and commit again.

Another way to accomplish the same thing is to do:

 

git commit --ammend
#this replaces the previous commit instead of creating a new one, and adds staged files into the commit
#NEVER do this for a commit that has already been pushed!!!!

 

 

 

Note that there is a major difference between a RESET and a REVERT. A reset will remove the commit from history (which can cause problems if you are working with other developers (what if you reset a commit that other developers had already starting adding changes to). A revert will rollback the changes made by a commit, but not destroy the history. So a revert does not delete a commit, it actually adds another commit (which rollsback the changes of the commit that it is reverting).

NEVER use reset on commits that you've pushed. But feel free to use it on commits that you have not yet pushed.

When you use reset, you removing an commit (and it's changes) and moving the HEAD back.

More on undoing changes:

RESET vs CHECKOUT - Reset will affect staging while checkout will affect your working directory. Ex: if you rest a file in staging it will remove the file from staging, but changes made to it will still be visible to you because it will not affect your working directory. If you checkout a file, it will be reverted to its state from the most recent commit. So if you make changes to a file and want to roll them back use checkout. If you make changes and add a file to staging, and later want to exclude it from a commit you are about to make, then use reset.

git reset --hard HEAD 
#removes all uncomitted changes to TRACKED files in both
#staging AND your working directory

git reset HEAD
#removes all uncommited changes to tracked files in staging
#but leaves your working directory alone

git reset HEAD somefile
#removes a file from staging

git checkout HEAD somefile
#makes somefile in the working directory match the most recent commit

git revert somecommithash
# reverts a commit (see notes above for the diff between reset and revert)
 

 

 

GIT STASH

git stash (takes everything out of your staging area and puts it somwhere else)

git stash pop (takes everything from some where else and applies it)

this is great for when you start making changes and you are on the wrong branch, you can call git stash, then switch to the proper branch, then call git stash pop

 

TO FIND AN OLD VERSION OF A FILE (there's got to be a better way to do this!)

use git log to find the hash of the commit that you are looking for (hopefully the comments will help you find the right commit)

then do: git show hashofcommit

 

HERE'S A SCENARIO OF A TYPICAL WORKFLOW SITUATION:

1. we had a branch called 'enhancements'

2. I created a new branch off of that called 'newbranch'

3. While I was working on 'newbranch', 'orignalbranch' was getting updated by other programmers.

4. When I was ready to push 'newbranch' to the remote repo I first had to merge in the changes from 'originalbranch' that happened after I branched it:

 

- commit what you have to newbranch

- git checkout originalbranch

- git pull origin originalbranch (update my local version of originalbranch)

- git checkout newbranch

- git merge originalbranch (merges upstream originalchanges to newbranch)

- git push -u origin newbranch (note that -u sets it up as a tracking branch)

 

 

ACCIDENTAL MERGES...

If you accidently merge on your local (for me I had master checked out and I did a git pull origin someotherbranch, which merged into master). You should revert the commit right away. If you don't and then do a git push, then master on the remote will get the merge, in which case you should to do

git revert -m 1 hashofmergecommit

see:http://git-scm.com/blog/2010/03/02/undoing-merges.html

BUT: if you revert on the master, you may have problems when you do actually want to merge that branch in (so it's best to revert the commit locally before you push to master!!!)

 

GIT TAGS:

http://git-scm.com/book/en/Git-Basics-Tagging

 

Also: here's a good video tutorial on team collaboration with github:

http://net.tutsplus.com/articles/general/team-collaboration-with-github/

 

// to overwrite your local master with the remote's verrsion of master

git fetch origin
git reset --hard origin/master
// if you do a pull and then wish you wouldn't have, you can revert it like this
// the @{1} part tells git to rollback to the 1st previous version of the branch
get reset --hard branchname@{1}

 

Here's a link on setting up SSH Keys:

https://help.github.com/articles/generating-ssh-keys

 

GIT CONFIG

show config settings:
git config --list

set up default editor:
git config --global core.editor "path to some exe goes here"

To set up gedit as the default editor on ubuntu:
git config --global core.editor "gedit -w -s"
(-w will block until the editor is closed and -s will force a new instance of gedit to open)

 

 

If you add files to the staging index and then decide you didn't want to:

git reset HEAD  (resets the staging area so that it matches HEAD)

 

GIT LOG

git log switches:

git log --pretty=format:"%h %s" --graph

git log --pretty=oneline  (note: other options, instead of 'oneline' are 'short', and 'full')

git log --since=2.weeks

git log branchname (view the log on a specific branch)

git log -3  (Show only the last 3 commits)

git log --since 1/1/2013 (shows commits since the date - you could also use --after)

git log --until 1/1/2013 (shows commits before the date - you could also use --before)

git log --author "Joe Smith"  (shows commits in which the author entry is Joe Smith)

git log --committer "Joe Smith" (shows commits made by Joe Smith)

git log -p (shows the patches made for a commit, this could come in really handy)

git log --stat (shows a count of lines changed for each file in a commit)

git log --abbrev-commit (abreviates the commit hash)

git log origin/master (shows the log for the master branch in the remote repo)

 

GIT STAGING

Before you can commit changes you must 'stage' them to what is known as the 'index'. This makes the changed files visible to git.

 

git add filename (adds a file to the index)

git add . (adds all modified files to the index)

git reset HEAD filename  (unstages a file  - removes it from the index)

git reset HEAD (removes all files from index and sets it to match HEAD)

git checkout checkout origin/master somefilename (overwrites the local version of somefile with the version that is on the master branch of the origin)

git add -u (will add the modified files to staging, the ones that were already being tracked, will NOT add untracked files)

 

GIT COMMIT

 

git commit -m "Some message" (commits all files from the index)

git commit --amend (When u need to change a commit because u forgot to add some files, or need to change the message)


if you forget to add a file to a commit, you can add it the the index (git add .) and then do git commit --ammend. This will add the file to the previous commit.

 

BRANCHING

When you first create a new branch, it will point to the same commit as the branch you created it from. But any new commits will only be applied to the new branch, and HEAD will be moved to the new branch.

good read:

http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging

Note: before you can checkout a remote branch, you should run fetch to pull all branches from the remote repo (git fetch origin)

'Tracking' branches are local branches that are linked to a remote branch. They allow you to run commands without specficying branch names (ex: git pull, instead of git pull origin somebranch). For more info: http://gitready.com/beginner/2009/03/09/remote-tracking-branches.html

git branch somenewbranch (creates a new branch)

git checkout somenewbranch (checks out a branch)

git checkout -b somenewbranchname (creates a branch and switches to it)

git branch -d nameofbranch  (deletes a branch that you no longer need)

git branch -D nameofbranch (forces delete even when you have not merged it)

To show branches
git branch -v. Shows branches

git branch --merged  (Shows branches that have been merged into the current branch)

git branch --no-merged  (Shows branches that have not been merged into the current branch)

git push origin branchname (pushes a branch to the remote repo)

 

git push origin --delete branchnamegoeshere (To delete a branch from the remote repo)

git branch -r (Shows branches on the remote (origin) repo)

 

 

 

 

the above is a shortcut for the following two commands:

git branch somenewbranchname

git checkout somenewbranchname

Note: you can do git status to see which branch you are working on.

 

 

WORKFLOW

Here's our workflow:

  1. clone a repo to your local machine
  2. make a branch
  3. do your edits
  4. Before pushing a topical branch to the remote repo, you should update your local master branch and then merge your local master branch into your topical branch. Then push the topical branch
  5. push the branch (git push orign branchname)
  6. on github (or gitlab) make a merge request to merge the branch into the master

Note that for step for, you may want to do a git fetch from master to try to merge in any new changes before you push your branch to the remote server.

'Topical' branches are used for quick fixes. You can also have long running branches (for example a 'future' branch)

 

 

MERGING

To merge (to master branch)

checkout master

git merge somebranchtomerge

If you get conflicts, the conflicted files will automatcially have markers added where the conflicts exist. Fix the conflicts and then add the -u switch to your add (tells git to mark conflicted files as resolved)

git add -u

 

to rollback a merge (let's say you merge and then get conflicts, you can roll it back)

git reset --merge

 

Typical merge into master (merging 'somebranch' into master):

 

git checkout master
git fetch origin //this will fetch somebranch in case you don't have it locally
git merge origin/somebranch
git push origin master

 

 

 

WORKING WITH REMOTE REPOS

pull = fetch + merge

$ git remote add pb git://github.com/paulboone/ticgit.git
Adds a remote repo and gives it the alias pb, then you can fetch or pull data
Note that fetch will get all branches from the remote repo

To switch to the master branch of that repo
git checkout pb/master

git push remotereponame branchname (the remote repo name is often origin)

If you and someone else clone at the same time and they push upstream and then you push upstream, your push will rightly be rejected. You’ll have to pull down their work first and incorporate it into yours before you’ll be allowed to push

 

git remote show origin

shows remote report URL and its tracked branches

 

to update your local version of a remote repo

git pull origin branchname (ex: git pull origin master)

 

overwrites the local version of somefile with the version that is on the master branch of the origin

git checkout checkout origin/master somefilename

 

If, for some reason, the remote repo's name changes you have to remove your local version of the remote and add the new one:

git remote rm origin

git remote add origin git@github.com:remwebdevelopment/html5-blastroids.git

 

You might also be able to do it in just one command by renaming the remote repo:

git remote set-url origin git@github.com:remwebdevelopment/html5-blastroids.git

 

IGNORING FILES AND REMOVING FILES

if you want to remove a file from the repo, but don't want to delete the file:

git rm --cached filename

if you wan to delete the file:

git rm filename

To ignore all files in a dir, create a file called .gitignore and then add this to the top of the file:

(Note that you should add and commit the ignore file into the repo)

!.gitignore

 

Here are some other notes on ignore files

!.gitignore

# a comment (comments are ignored)
*.a (ignore .a files)
!lib.a (but do track lib.a, even though you’re ignoring .a files above)
/TODO (only ignore the root TODO file, not a subdir called /TODO)
build/ (ignore all files in any build/ directory within the project)
doc/*.txt (ignore doc/notes.txt, but not doc/server/arch.txt)
*.*~ (this one comes in handy for all the temp files that ubuntu creates)

 

switches you can use with 'git log'

git log --pretty=format:"%h %s" --graph

git log --since=2.weeks

-(n) Show only the last n commits
--since, --after Limit the commits to those made after the speciï¬ï¿½ed date.
--until, --before Limit the commits to those made before the speciï¬ï¿½ed date.
--author Only show commits in which the author entry matches the speciï¬ï¿½ed string.
--committer Only show commits in which the committer entry matches the speciï¬ï¿½ed string.

 

Making changes

# When u need to change a commit because u forgot to add some files, or need to change the message
git commit --amend

#To unstage a file (remove it from the index)
git reset HEAD filename

#To revert (this is for files that are in staging and UNCOMMITTED)
git checkout -- filename

 

CHANGE REPO NAME ON GITHUB

I accidentally realized that my repo on github was named incorrectly. So I had to figure out first how to rename it on github, then how to change the settings on my local version so that it knew the new name of the remote repo on github. To change a repo name in github, go to the repo's homepage and you'll see a link to 'Admin' near the top right. You can change it's name in the admin settings. To update your local repo, I used this command:

git remote set-url origin git@github.com:remwebdevelopment/html5-blastroids.git

That took care of it. You can use this command to show your repo's remote setting (origin?):

git remote show origin

 

SHOW FILES THAT CHANGED ON LAST COMMIT:

git show --name-only

 

 

GIT SUBMODULES

You can include other git repos inside your project repo. See this link for more info:

http://git-scm.com/book/en/Git-Tools-Submodules

When you first clone a repo that includes another repo as a submodule, you must also run these commands to pull down the contents of the submodule

 

git submodule init
git submodule update

// in order to refresh the submodule so that it gets the latest updates from it's origin
// cd into the directory of submodule, and then do:
git pull

 

YOU CAN ALSO ADD REMOTE REPOS TO YOUR PROJECT (not sure how this differs from a submodule), but it allows your project to pull and update from the remote so that you are always getting the latest code from the repo that you are using as a third party, here's an example:

 

git remote add laravel https://github.com/laravel/laravel
git fetch laravel
git merge laravel/develop
git add . && git commit -am "commit the laravel application structure"


 

 

SETTING UP GITWEB (easier than I thought)

 

// install gitweb
sudo apt-get install gitweb

// create a dir in /var/www
mkdir /var/www/git

// create a dir for your repo
mkdir /var/www/git/somerepo

// you have to create a bare clone of the repo you want to put on gitweb. I bare repo has no working copy.
// the shared flag makes the repo group writable
sudo git clone --bare --share ~/somerepo /var/www/git/somerepo

//edit the gitweb.conf file
sudo vi /etc/gitweb.conf

// change the projectroot setting to /var/www/git

in browser, go to http://localhost/gitweb

// to clone a repo on git web
git clone user@host:reponame ( ex: git clone niallkader@192.168.1.71:backbone-boilerplate )

 

 

 

 

Here's reference (can't remember where I found this reference)...


git config

Sets configuration values for your user name, email, gpg key, preferred diff algorithm, file formats and more.

Example: git config --global user.name "My Name"
git config --global user.email "user@domain.com"

cat ~/.gitconfig
[user]
name = My Name
email = user@domain.com

git init

Initializes a git repository – creates the initial ‘.git’ directory in a new or in an existing project.

Example: cd /home/user/my_new_git_folder/
git init


git clone

Makes a Git repository copy from a remote source. Also adds the original location as a remote so you can fetch from it again and push to it if you have permissions.

Example: git clone git@github.com:user/test.git

git add

Adds files changes in your working directory to your index.

Example: git add .

git mv
renames a folder or file
Example: git mv oldfoldername newfoldername

git rm

Removes files from your index and your working directory so they will not be tracked.

Example: git rm filename

git commit

Takes all of the changes written in the index, creates a new commit object pointing to it and sets the branch to point to that new commit.

Examples: git commit -m ‘committing added changes’
git commit -a -m ‘committing all changes, equals to git add and git commit’

git status

Shows you the status of files in the index versus the working directory. It will list out files that are untracked (only in your working directory), modified (tracked but not yet updated in your index), and staged (added to your index and ready for committing).

Example: git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# README
nothing added to commit but untracked files present (use "git add" to track)

git branch

Lists existing branches, including remote branches if ‘-a’ is provided. Creates a new branch if a branch name is provided.

Example: git branch -a
* master
remotes/origin/master

git checkout

Checks out a different branch – switches branches by updating the index, working tree, and HEAD to reflect the chosen branch.

Example: git checkout newbranch

git merge

Merges one or more branches into your current branch and automatically creates a new commit if there are no conflicts.

Example: git merge newbranchversion

git reset

Resets your index and working directory to the state of your last commit.

Example: git reset --hard HEAD

git stash

Temporarily saves changes that you don’t want to commit immediately. You can apply the changes later.

Example: git stash
Saved working directory and index state "WIP on master: 84f241e first commit"
HEAD is now at 84f241e first commit
(To restore them type "git stash apply")

git tag

Tags a specific commit with a simple, human readable handle that never moves.

Example: git tag -a v1.0 -m 'this is version 1.0 tag'

git fetch

Fetches all the objects from the remote repository that are not present in the local one.

Example: git fetch origin

git pull

Fetches the files from the remote repository and merges it with your local one. This command is equal to the git fetch and the git merge sequence.

Example: git pull origin

git push

Pushes all the modified local objects to the remote repository and advances its branches.

Example: git push origin master

git remote

Shows all the remote versions of your repository.

Example: git remote
origin

git log

Shows a listing of commits on a branch including the corresponding details.

Example: git log
commit 84f241e8a0d768fb37ff7ad40e294b61a99a0abe
Author: User <user@domain.com>
Date: Mon May 3 09:24:05 2010 +0300

first commit

git show

Shows information about a git object.

Example: git show
commit 84f241e8a0d768fb37ff7ad40e294b61a99a0abe
Author: User <user@domain.com>
Date: Mon May 3 09:24:05 2010 +0300

first commit

diff --git a/README b/README
new file mode 100644
index 0000000..e69de29

git ls-tree

Shows a tree object, including the mode and the name of each item and the SHA-1 value of the blob or the tree that it points to.

Example: git ls-tree master^{tree}
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 README

git cat-file

Used to view the type of an object through the SHA-1 value.

Example: git cat-file -t e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
blob

git grep

Lets you search through your trees of content for words and phrases.

Example: git grep "www.siteground.com" -- *.php

git diff

Generates patch files or statistics of differences between paths or files in your git repository, or your index or your working directory.

Example: git diff

gitk

Graphical Tcl/Tk based interface to a local Git repository.

Example: gitk

Gitk

git instaweb

Runs a web server with an interface into your local repository and automatically directs a web browser to it.

Example: git instaweb --httpd=webrick
git instaweb --stop

Git Instaweb

git archive

Creates a tar or zip file including the contents of a single tree from your repository.

Example: git archive --format=zip master^ README >file.zip

git gc

Garbage collector for your repository. Optimizes your repository. Should be run occasionally.

Example: git gc
Counting objects: 7, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), done.
Total 7 (delta 1), reused 0 (delta 0)

git fsck

Does an integrity check of the Git file system, identifying corrupted objects.

Example: git fsck

git prune

Removes objects that are no longer pointed to by any object in any reachable branch.

Example: git prune