Git Tutorial

git

https://www.atlassian.com/git/tutorials/
https://git-scm.com/docs/gittutorial - done reading
http://rogerdudler.github.io/git-guide/
https://www.git-tower.com/blog/git-for-subversion-users-cheat-sheet/

git help config

git config --global user.name "Your Name"
git config --global user.email "Your Email"

cd project
git init
git add .
git commit -m "Commit message"

git add file1 file2 file3
git diff --cached

Without the --cached option, 'git diff' will show you any changes that you've 
made but not yet added to the staging area.

git status

git reset HEAD fileName // Unstage a file

git commit -a

The above command automatically add any modified (but not new) files to the 
staging area, and commit, all in one step.

Though not required, it is a good idea to begin the commit message with a single 
short (less than 50 characters) line summarizing the change, followed by a blank 
line, and then a more thorough description.  The text up to the first blank line 
in a commit message is treated as the commit title, and that title is used 
throughout Git.  For example, git-format-patch turns a commit into email, and it 
uses the title as the Subject line, and the rest of the commit in the body.

git log
git log -p // see the complete diffs at each step
git log --stat --summary // see just an overview of the change

git branch branchName // create a local branch
git branch // list existing local branches
git branch -a // list existing branches, including remote branches

The "master" branch is a default branch that was created for you automatically.  
The asterisk indicate the current branch.

git checkout experimental // switch to a local branch named "experimental"
git checkout master // switch back to the local branch named "master"

git merge experimental // merged changes from the local branch named "experimental"
  // into the current branch.

git branch -d experimental // delete a local branch named "experimental"

Suppose that Alice has started a new project with a Git repository in 
/home/alice/project, and that Bob, who has a home directory on the same machine 
want to contribute.  Bob begins with:

git clone /home/alice/project myrepo

This creates a new directory named myrepo containing a clone of Alice's 
repository.  The clone is on an equal footing with the original project, 
possessing its own copy of the original project's history.  Bob then make some 
changes and commits them.  When he is ready, he tells Alice to pull changes 
from his repository at /home/bob/myrepo.  Alice does with this:

cd /home/alice/project
git pull /home/bob/myrepo master

This merge the changes from Bob's master branch into Alice's current branch.  If 
Alice has made her own changes in the meantime, she may need to manually fix any 
conflicts.

In general, we would want to commit our local changes before doing a pull.  If 
Bob’s work conflicts with what Alice did since their histories forked, Alice 
will use her working tree and the index to resolve conflicts, and existing 
local changes will interfere with the conflict resolution process (Git will 
still perform the fetch but will refuse to merge --- Alice will have to get rid 
of her local changes in some way and pull again when this happens).

Alice can peek at what Bob did without merging first, using the "fetch" command.  
This allows Alice to inspect what Bob did, using a special symbol "FETCH_HEAD", 
in order to determine if he has anything worth pulling, like this:

git fetch /home/bob/myrepo master
git log -p HEAD..FETCH_HEAD

This operation is safe even if Alice has uncommitted local changes. The range 
notation "HEAD..FETCH_HEAD" means "show everything that is reachable from the 
FETCH_HEAD but exclude anything that is reachable from HEAD". Alice already 
knows everything that leads to her current state (HEAD), and reviews what Bob 
has in his state (FETCH_HEAD) that she has not seen with this command.

If Alice wants to visualize what Bob did since their histories forked she can 
issue the following command:

gitk HEAD..FETCH_HEAD

Alice may want to view what both of them did since they forked. She can use 
three-dot form instead of the two-dot form:

gitk HEAD...FETCH_HEAD

This means "show everything that is reachable from either one, but exclude 
anything that is reachable from both of them".

These range notation can be used with both gitk and "git log".

After inspecting what Bob did, if there is nothing urgent, Alice may decide to 
continue working without pulling from Bob. If Bob’s history does have something 
Alice would immediately need, Alice may choose to stash her work-in-progress 
first, do a "pull", and then finally unstash her work-in-progress on top of the 
resulting history.

When you are working in a small closely knit group, it is not unusual to 
interact with the same repository over and over again. By defining remote 
repository shorthand, you can make it easier:

git remote add bob /home/bob/myrepo

With this, Alice can perform the first part of the "pull" operation alone using 
the git fetch command without merging them with her own branch, using:

git fetch bob

git log -p master..bob/master

The above command shows a list of all the changes that Bob made since he 
branched from Alice’s master branch.

After examining those changes, Alice could merge the changes into her master 
branch:

git merge bob/master

This merge can also be done by pulling from her own remote-tracking branch, 
like this:

git pull . remotes/bob/master

Note that git pull always merges into the current branch, regardless of what 
else is given on the command line.

Later, Bob can update his repo with Alice’s latest changes using:

git pull

Note that he doesn’t need to give the path to Alice’s repository; when Bob 
cloned Alice’s repository, Git stored the location of her repository in the 
repository configuration, and that location is used for pulls:

git config --get remote.origin.url

Git also keeps a pristine copy of Alice’s master branch under the name 
"origin/master":

git branch -r

git show c82a22c39c
git show HEAD // Tip of the current branch
git show experimental // Tip of the local branch named "experimental"

Every commit usually has one "parent" commit which points to the previous state 
of the project:

git show HEAD^  # to see the parent of HEAD
git show HEAD^^ # to see the grandparent of HEAD
git show HEAD~4 # to see the great-great grandparent of HEAD

git show HEAD^1 # show the first parent of HEAD (same as HEAD^)
git show HEAD^2 # show the second parent of HEAD

Every commit usually has one "parent" commit which points to the previous state 
of the project.  Merge commits may have more than one parent.  What does this 
mean?

You can also give commits names of your own after running:

git tag v2.5 1b2e1d63ff

We can refer to 1b2e1d63ff by the name "v2.5". If you intend to share this name 
with other people (for example, to identify a release version), you should 
create a "tag" object, and perhaps sign it; see git-tag[1] for details.

Any Git command that needs to know a commit can take any of these names. For 
example:

git diff v2.5 HEAD     # compare the current HEAD to v2.5
git branch stable v2.5 # start a new branch named "stable" based
             # at v2.5
git reset --hard HEAD^ # reset your current branch and working
             # directory to its state at HEAD^

Be careful with that last command: in addition to losing any changes in the 
working directory, it will also remove all later commits from this branch. If 
this branch is the only branch containing those commits, they will be lost. 
Also, don’t use git reset on a publicly-visible branch that other developers 
pull from, as it will force needless merges on other developers to clean up the 
history. If you need to undo changes that you have pushed, use git revert 
instead.

The git grep command can search for strings in any version of your project.  For 
example:

git grep "hello" v2.5

searches for all occurrences of "hello" in v2.5.

If you leave out the commit name, git grep will search any of the files it 
manages in your current directory.

Many Git commands also take sets of commits, which can be specified in a number 
of ways. Here are some examples with git log:

git log v2.5..v2.6            # commits between v2.5 and v2.6
git log v2.5..                # commits since v2.5
git log --since="2 weeks ago" # commits from the last 2 weeks
git log v2.5.. Makefile       # commits since v2.5 which modify
                # Makefile
You can also give git log a "range" of commits where the first is not 
necessarily an ancestor of the second; for example, if the tips of the branches 
"stable" and "master" diverged from a common commit some time ago, then

git log stable..master

will list commits made in the master branch but not in the stable branch, while

git log master..stable

will show the list of commits made on the stable branch but not the master 
branch.

The git log command has a weakness: it must present commits in a list. When the 
history has lines of development that diverged and then merged back together, 
the order in which git log presents those commits is meaningless.

Most projects with multiple contributors (such as the Linux kernel, or Git 
itself) have frequent merges, and gitk does a better job of visualizing their 
history. For example,

gitk --since="2 weeks ago" drivers/

allows you to browse any commits from the last 2 weeks of commits that modified 
files under the "drivers" directory. (Note: you can adjust gitk’s fonts by 
holding down the control key while pressing "-" or "+".)

Finally, most commands that take filenames will optionally allow you to precede 
any filename by a commit, to specify a particular version of the file:

git diff v2.5:Makefile HEAD:Makefile.in

You can also use git show to see any such file:

git show v2.5:Makefile
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License