Git allows and encourages you to have multiple local branches that can be entirely independent of each other.
|
Linux (Debian Based)
$ sudo apt-get install git-core
:)
$ git config --global user.name "Your Name"
$ git config --global user.email "you@digitalbrandgroup.com"
Unix/Mac users:
git config --global core.autocrlf input
git config --global core.safecrlf true
Windows users:
git config --global core.autocrlf true
git config --global core.safecrlf true
$ git config --global core.editor emacs
Another useful option you may want to configure is the default diff tool to use to resolve merge conflicts.
$ git config --global merge.tool vimdiff
$ git init
Initialized empty Git repository in /Users/rejah/working/directory/.git/
$ git clone git@letzgame.com:testing.git
Cloning into 'testing'...
remote: Counting objects: 21, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 21 (delta 2), reused 0 (delta 0)
Receiving objects: 100% (21/21), 2.50 MiB, done.
Resolving deltas: 100% (2/2), done
$ git add hello.php
$ git commit -m "First Commit"
[master (root-commit) 9416416] First Commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 hello.php
git status
to check the current status of the repo.
$ git status
# On branch master
nothing to commit (working directory clean)
$ git status
# On branch master
# Changes not staged for commit:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: hello.php
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git add hello.php
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: hello.php
#
The change to the hello.php file has been staged. This means that git now knows about the change, but the change hasn’t been permanently recorded in the repository yet. The next commit operation will include the staged changes. If you decide you don’t want to commit that change after all, the status command reminds you that the git reset command can be used to unstage that change.
Suppose you edited three files (a.php
, b.php
, and c.php
). Now you want to commit all the changes, but you want the changes in a.php
and b.php
to be a single commit, while the changes to c.php
are not logically related to the first two files and should be a separate commit.
git add a.php
git add b.php
git commit -m "Changes for a and b"
git add c.php
git commit -m "Unrelated change to c"
By separating staging and committing, you have the ability to easily fine tune what goes into each commit.
git commit
|
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: hello.php
#
On the first line, enter the comment: “Test Commit”. Save the file and exit the editor.git commit -m "Test Commit"
This question tells reviewers what to expect in the commit, allowing them to more easily identify and point out unrelated changes.
A more useful commit message might be:
Redirect user to the requested page after login
http://letzgame.com/path/to/page users where being redirected to the home page after login, which is less useful than redirecting to the page they had originally requested.
before being redirected to the login form.* Store requested path in a session variable*
Redirect to the stored location after successfully logging in the user
Getting a listing of what changes have been made is the function of the git log
command.
$ git log
commit 1f7ec5eaa8f37c2770dae3b984c55a1531fcc9e7
Author: Rejah
Date: Sat Apr 13 15:20:42 2013 -0400
Added a comment
commit 582495ae59ca91bca156a3372a72f88f6261698b
Author: Rejah
Date: Sat Apr 13 15:20:42 2013 -0400
Added a default value
$ git log --pretty=oneline
1f7ec5eaa8f37c2770dae3b984c55a1531fcc9e7 Added a comment
582495ae59ca91bca156a3372a72f88f6261698b Added a default value
323e28d99a07d404c04f27eb6e415d4b8ab1d615 Using ARGV
94164160adf8faa3119b409fcfcd13d0a0eb8020 First Commit
You have a great deal of control over exactly what the log
command displays.
git log --pretty=oneline --max-count=2
git log --pretty=oneline --since='5 minutes ago'
git log --pretty=oneline --until='5 minutes ago'
git log --pretty=oneline --author=
git log --pretty=oneline --all
$ git log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short
* 1f7ec5e 2013-09-13 | Added a comment (HEAD, master) [Rejah]
* 582495a 2013-09-13 | Added a default value [Rejah]
* 323e28d 2013-09-13 | Using ARGV [Rejah]
* 9416416 2013-09-13 | First Commit [Rejah]
$ git checkout 9416416
Note: checking out '9416416'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at 9416416... First Commit
$ git checkout master
Previous HEAD position was 9416416... First Commit
Switched to branch 'master'
$ git tag v1
Now you can refer to the current version of the program as v1.
$ git checkout v1
Previous HEAD position was 582495a... Added a default value
HEAD is now at 1f7ec5e... Added a comment
$ git checkout v1-beta
Previous HEAD position was 1f7ec5e... Added a comment
HEAD is now at 582495a... Added a default value
tag
command$ git tag
v1
v1-beta
$ git log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short master --all
* 1f7ec5e 2013-04-13 | Added a comment (v1, master) [Jim Weirich]
* 582495a 2013-04-13 | Added a default value (HEAD, v1-beta) [Jim Weirich] * 323e28d 2013-04-13 | Using ARGV [Jim Weirich]
* 9416416 2013-04-13 | First Commit [Jim Weirich]
$ git tag -d oops
Deleted tag 'oops' (was a10293f)
Sometimes you have modified a file in your local working directory and you wish to just revert to what has already been committed. The checkout command will handle that.
git checkout hello.php
git status
vim hello.php
$ git reset HEAD hello.php
Unstaged changes after reset:
M hello.php
The reset
command resets the staging area to be whatever is in HEAD. This clears the staging area of the change we just staged.
The reset
command (by default) doesn’t change the
working directory. So the working directory still has the unwanted
code in it.
We can use the checkout
command to remove the unwanted change from the working directory.
Change that you have already committed was not correct and you wish to undo that commit.
$ git revert HEAD --no-edit
[master a10293f] Revert "Oops, we didn't want this commit" 1 files changed, 1 insertions(+), 1 deletions(-)
Since we were undoing the very last commit we made, we were able to use HEAD
as the argument . We can revert any arbitrary commit earlier in history by simply specifying its hash value.
--no-edit
in the output can be ignored. used to generate the output without opening the editor.$ git reset --hard v1
HEAD is now at 1f7ec5e Added a comment
$ git hist
* 1f7ec5e 2013-04-13 | Added a comment (HEAD, master) [Rejah]
* 582495a 2013-04-13 | Added a default value (v1-beta) [Rejah]
After you make the commit, you realize that any good author comment should have an email included. Update the hello program to include an email.
git add hello.php
git commit --amend -m "Add an author/email comment"
$ git checkout -b greet
$ git status
git checkout -b <branchname>
is a shortcut for git branch <branchname>
followed by a git checkout <branchname>
.
Notice that the git status command reports that you are on the ‘greet’ branch.
$ git checkout master
Switched to branch 'master'
$ git merge master
Merge made by recursive. README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 README
$ git checkout newbranch
Switched to branch 'newbranch'
$ git merge master
Auto-merging lib/hello.php
CONFLICT (content): Merge conflict in lib/hello.php
Automatic merge failed; fix conflicts and then commit the result.
If you open lib/hello.php, you will see:
<<<<<<< HEAD:mergetest
This is my third line
======= This is a fourth line I am adding
>>>>>>> 4e2b407f501b68f8588aa645acafffa0224b9b78:mergetest
<<<<<<<: Indicates the start of the lines that had a merge conflict. The first set of lines are the lines from the file that you were trying to merge the changes into.
=======: Indicates the break point used for comparison. Breaks up changes that user has committed (above) to changes coming from merge (below) to visually see the differences.
>>>>>>>: Indicates the end of the lines that had a merge conflict.
You resolve a conflict by editing the file to manually merge the parts of the file that git had trouble merging.
This may mean discarding either your changes or someone else's or doing a mix of the two.
You will also need to delete the '<<<<<<<', '=======', and '>>>>>>>' in the file.
Commit the Conflict Resolution
git add the file(s)
$ git add -A
git commit and git push (Push only for branches tracked.)
$git commit -m "Resolve Conflict in merge A and B"
$git push
$ apt-get install meld
$ git config --global merge.tool meld
Meld
Mac$ git remote
origin
We see that the cloned repository knows about a remote repository$ git remote show origin
* remote origin
Fetch URL: git@letzgame.com:testing.git
Push URL: git@letzgame.com:testing.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
Now we see that the remote repository “origin” is simply the original central repository.
Remote repositories typically live on a separate machine, possibly a centralized server.
There is nothing particularly special about the name “origin”, however
the convention is to use the name “origin” for the primary centralized
repository (if there is one).
$ git branch
* master
That’s it, only the master branch is listed. $ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/greet
remotes/origin/master
Git has all the commits from the original repository, but branches in
the remote repository are not treated as local branches here. If we
want our own , we need to create it ourselves.Let’s add the testing.git repo to our original repo.
git remote add git@letzgame.com:testing.git
$ git branch --track newbranch origin/greet
Branch newbranch set up to track remote branch newbranch from origin.
$ git branch -a
newbranch
* master
remotes/origin/HEAD -> origin/master
remotes/origin/newbranch
remotes/origin/master
We can now see the greet branch in the branch list and in the log.The “git fetch” command will fetch new commits from the remote repository, but it will not merge these commits into the local branches.$ git fetch
From /Users/jim/working/git/git_immersion/auto/hello 2fae0b2..2e4c559 master -> origin/master
$ git merge origin/master
Updating 2fae0b2..2e4c559 Fast-forward README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
origin is the name of the repository receiving the changes we are pushing. (Remember, we added it as a remote)$ git push origin master To git@letzgame.com:testing.git
2e4c559..3923dd5 master -> master
We’re not going to go through the process of creating another change and pulling it again, but we do want you to know that doing:
$ git pull origin master
is indeed equivalent to the two steps:
$ git fetch
$ git merge origin/master
git svn clone [SVN repo URL]