首页 » git » 正文

GIT使用最佳实践

四层结构

ur1

最佳实践

第一条,如果自从上次pull以后,本地没有任何改变,你想把远程别人的改变拉下来,使用如下命令,两者结果相同,因为只有一个远程的更改。

git pull
git pull --rebase

第二条,如果自从上次pull以后,本地有改变并且已经提交,你想把远程别人的分支拉下来,使用如下命令,前者形成菱形历史,后者是线性历史。

git pull
git pull --rebase

第三条,当一个功能分支开发完毕,想合并,使用如下命令,形成菱形历史。

git merge

第四条,pull是fetch+merge的结合,做完以后需要提交,再push回远程库。

第五条,如下命令和git pull –rebase产生同样的结果。

git fetch origin -> git rebase −p origin/develop

第六条,如果你本地的分支(提交的)已经搞得乱起八糟了,使用如下命令回滚到上次你git pull的状态。

git reset --hard origin/master

第七条,如果你本地的一个文件被你搞乱了,你不想要了,你能用如下命令来回复到上次git pull的文件状态,请注意不要和git checkout branch搞混,那是转换分支。

git checkout file_name

第八条,如果你本地改变了很多文件,发现你在错误的分支上,则创建一个新的分支。

git checkout -b new_branch_name  # just create a new branch
git add .                      # add the changes files
git commit -m"your message"    # and commit them

第九条,如果你rebasing过程中出现了问题,想回滚,请使用如下命令:

git rebase --abort

第十条,如果你克隆一个项目后,然后想checkout远程分支,请使用如下命令:

git clone git@****:*.git
git checkout develop
或者 git checkout -b develop origin/develop

第十一条,GIT invokes cURL when running over HTTP. You can store secure credentials by setting up a .netrc file in your user’s home directory, and making it private to the user (0600 in Linux).

The contents of the file provide the username and password per remote domain.

/home/robert/.netrc

machine ip-address
login username
password password

第十二条, GIT的分支分为本地和远程,git branch和git branch -r可以显示本地和远程分支,远程分支在remotes/origin/*下面,通过git branch -a可以看到,另外,远程分支的origin其实是refs/remotes/origin/的别名,通过more .git/config可以看到,本地分支在refs/heads/*下面,所以,master和refs/heads/master其实是一个分支,origin/master和ref/remotes/origin/master则是一个分支, 前后这一个是本地分支一个是远程分支。

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git branch
* develop
  master
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git branch -r
  origin/HEAD -> origin/master
  origin/develop
  origin/master
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git branch -a
* develop
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ more .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = http://10.77.144.192:11824/develop/athena-example.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master
[branch "develop"]
	remote = origin
	merge = refs/heads/develop
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ more .git/
branches/       config          FETCH_HEAD      hooks/          info/           objects/        packed-refs     
COMMIT_EDITMSG  description     HEAD            index           logs/           ORIG_HEAD       refs/           
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ more .git/HEAD
ref: refs/heads/develop

第十二条, 本地和远程分支保存在.git/refs下面,refs/heads是本地分支,refs/remotes是远程分支,本地分支可以直接写分支名称,例如:master, 远程必须得加限定符origin, 例如, origin/master, 在.git/config里面配置origin其实指向远程的remotes/origin/master。

├── heads
│   ├── develop
│   └── master
├── remotes
│   └── origin
│   ├── develop
│   └── HEAD
└── tags

第十三条,12条中的小写的heads,指的是任何一个本地的branch, 这个和大写的HEAD没有关系,origin/HEAD一般指向远程的origin/master,

  origin/HEAD -> origin/master
  origin/develop
  origin/master

本地也有一个HEAD,表明的是上次checkout的那个分支,也可以通过more .git/HEAD看到指向的是本地哪个分支。

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ more .git/HEAD
ref: refs/heads/develop

第十四条,查看本地develop和远程develop之间的差别。

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git diff develop origin/develop
diff –git a/abc.txt b/abc.txt
index 3cda2ad..e69de29 100644
— a/abc.txt
+++ b/abc.txt
@@ -1 +0,0 @@
-oooooootest

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git rev-list origin/develop..develop
10131e447c1ee3599c1aeb3bfcbd49144df01d56
f97bfa757579e1cd7bb08ee3c2e51134c78dbcd0
3638bf662b3f49ad22c769a947aa60806c0865d4

注意,origin/develop..develop是有顺序的。

第十五条,Detached HEAD状态,就是临时切换到某个commit的点上,但是没有branch,更改后还可以创建新的branch.

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git log -3
commit 10131e447c1ee3599c1aeb3bfcbd49144df01d56
Author: Your Name <you@example.com>
Date:   Tue May 26 16:09:52 2015 +0800

    test

commit f97bfa757579e1cd7bb08ee3c2e51134c78dbcd0
Author: Your Name <you@example.com>
Date:   Tue May 26 16:09:04 2015 +0800

    test

commit 3638bf662b3f49ad22c769a947aa60806c0865d4
Author: Your Name <you@example.com>
Date:   Tue May 26 16:04:55 2015 +0800

    testwq
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git checkout 10131e447c1ee3599c1aeb3bfcbd49144df01d56
Note: checking out '10131e447c1ee3599c1aeb3bfcbd49144df01d56'.

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 10131e4... test
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git status
HEAD detached at 10131e4
nothing to commit, working directory clean

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git checkout -b mytest1
Switched to a new branch 'mytest1'
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git status
On branch mytest1
nothing to commit, working directory clean

第十六条, 浏览任意库的存储结构。

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git ls-tree master
100644 blob 733a3eda91e1df9bc322bf31f1872ea19477c921	.gitignore
040000 tree 4787e9fa11bdcf2dfebac0ec73c00ec17e2e432b	athena-example-data
040000 tree 168481c622003f6b6a6237d7b5d994cb070d1caa	athena-example-rest
040000 tree ebd2b01a2dbe7becbac7a3817d0d3d83f2473ced	athena-example-service
100644 blob 906e0154efe29d673bed01684b592d02910f6ce9	pom.xml
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git ls-tree 168481c622003f6b6a6237d7b5d994cb070d1caa
100644 blob 328de9a35dd49694aad1ad09e47feb3ba1f210e9	.gitignore
100644 blob 15170695ce10fc583722b5b442971c80b68ae19f	assembly.xml
100644 blob f5879e034986e295067094cb3e9dc99b86b514a5	pom.xml
040000 tree 0ac8338b5230cd84620c53d4cb39a542fa98889a	src

第十七条, 以图形方式浏览log。

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git log --graph
* commit 10131e447c1ee3599c1aeb3bfcbd49144df01d56
| Author: Your Name <you@example.com>
| Date:   Tue May 26 16:09:52 2015 +0800
| 
|     test
|  
* commit f97bfa757579e1cd7bb08ee3c2e51134c78dbcd0
| Author: Your Name <you@example.com>
| Date:   Tue May 26 16:09:04 2015 +0800
| 
|     test
|  
* commit 3638bf662b3f49ad22c769a947aa60806c0865d4
| Author: Your Name <you@example.com>
| Date:   Tue May 26 16:04:55 2015 +0800
| 
|     testwq

第十七条,显示某一次提交的内容。

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git log -3
commit 10131e447c1ee3599c1aeb3bfcbd49144df01d56
Author: Your Name <you@example.com>
Date:   Tue May 26 16:09:52 2015 +0800

    test

commit f97bfa757579e1cd7bb08ee3c2e51134c78dbcd0
Author: Your Name <you@example.com>
Date:   Tue May 26 16:09:04 2015 +0800

    test

commit 3638bf662b3f49ad22c769a947aa60806c0865d4
Author: Your Name <you@example.com>
Date:   Tue May 26 16:04:55 2015 +0800

    testwq
robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git show 10131e447c1ee3599c1aeb3bfcbd49144df01d56
commit 10131e447c1ee3599c1aeb3bfcbd49144df01d56
Author: Your Name <you@example.com>
Date:   Tue May 26 16:09:52 2015 +0800

    test

diff --git a/abc.txt b/abc.txt
index 9daeafb..3cda2ad 100644
--- a/abc.txt
+++ b/abc.txt
@@ -1 +1 @@
-test
+oooooootest

第十八条, 对比两个commit的不同,或者两个commit的两个文件的不同,显示文件内容。

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git diff  f97bfa757579e1cd7bb08ee3c2e51134c78dbcd0
diff --git a/abc.txt b/abc.txt
index 9daeafb..3cda2ad 100644
--- a/abc.txt
+++ b/abc.txt
@@ -1 +1 @@
-test
+oooooootest

robert@robert-ThinkPad-X200:~/working/githome/athena-example$ git diff  f97bfa757579e1cd7bb08ee3c2e51134c78dbcd0 10131e447c1ee3599c1aeb3bfcbd49144df01d56 abc.txt
diff --git a/abc.txt b/abc.txt
index 9daeafb..3cda2ad 100644
--- a/abc.txt
+++ b/abc.txt
@@ -1 +1 @@
-test
+oooooootest

第十九条, 对比两个commit的不同,并仅仅显示文件名称,或者显示某一个commit的文件列表, 在git log和git show中使用–name-status选项。

robert@robert-ThinkPad-X200:~/working/githome/vesta-id-generator$ git log --name-status -2
commit f0fe90d66016130168778daf531267f12bd3ad8f
Author: Your Name <you@example.com>
Date:   Wed May 27 10:40:08 2015 +0800

    add the machine id provider so that it can support zookeeper in future

M       vesta-service/src/main/java/com/wanda/vesta/service/impl/AbstractIdServiceImpl.java
D       vesta-service/src/main/java/com/wanda/vesta/service/impl/IdServiceImplOpt.java
A       vesta-service/src/main/java/com/wanda/vesta/service/impl/MachineIdProvider.java
A       vesta-service/src/main/java/com/wanda/vesta/service/impl/PropertyMachineIdProvider.java
M       vesta-service/src/main/resources/spring/vesta-service.xml

commit 97bb2c1a9351ea2c6f7d03c6363e31adb47e2139
Author: Your Name <you@example.com>
Date:   Tue May 26 20:00:29 2015 +0800

    implement rest service for makeid and transtime

M       vesta-rest/src/main/java/com/wanda/vesta/rest/IdController.java
robert@robert-ThinkPad-X200:~/working/githome/vesta-id-generator$ git show --name-status f0fe90d66016130168778daf531267f12bd3ad8f
commit f0fe90d66016130168778daf531267f12bd3ad8f
Author: Your Name <you@example.com>
Date:   Wed May 27 10:40:08 2015 +0800

    add the machine id provider so that it can support zookeeper in future

M       vesta-service/src/main/java/com/wanda/vesta/service/impl/AbstractIdServiceImpl.java
D       vesta-service/src/main/java/com/wanda/vesta/service/impl/IdServiceImplOpt.java
A       vesta-service/src/main/java/com/wanda/vesta/service/impl/MachineIdProvider.java
A       vesta-service/src/main/java/com/wanda/vesta/service/impl/PropertyMachineIdProvider.java
M       vesta-service/src/main/resources/spring/vesta-service.xml
robert@robert-ThinkPad-X200:~/working/githome/vesta-id-generator$ git diff --name-status 97bb2c1a9351ea2c6f7d03c6363e31adb47e2139 f0fe90d66016130168778daf531267f12bd3ad8f
M       vesta-service/src/main/java/com/wanda/vesta/service/impl/AbstractIdServiceImpl.java
D       vesta-service/src/main/java/com/wanda/vesta/service/impl/IdServiceImplOpt.java
A       vesta-service/src/main/java/com/wanda/vesta/service/impl/MachineIdProvider.java
A       vesta-service/src/main/java/com/wanda/vesta/service/impl/PropertyMachineIdProvider.java
M       vesta-service/src/main/resources/spring/vesta-service.xml
robert@robert-ThinkPad-X200:~/working/githome/vesta-id-generator$ git diff --name-status 97bb2c1a9351ea2c6f7d03c6363e31adb47e2139 f0fe90d66016130168778daf531267f12bd3ad8f vesta-service/src/main/resources/spring/vesta-service.xml
M       vesta-service/src/main/resources/spring/vesta-service.xml
robert@robert-ThinkPad-X200:~/working/githome/vesta-id-generator$ git diff 97bb2c1a9351ea2c6f7d03c6363e31adb47e2139 f0fe90d66016130168778daf531267f12bd3ad8f vesta-service/src/main/resources/spring/vesta-service.xml
diff --git a/vesta-service/src/main/resources/spring/vesta-service.xml b/vesta-service/src/main/resources/spring/vesta-service.xml
index 23c38a9..4333441 100644
--- a/vesta-service/src/main/resources/spring/vesta-service.xml
+++ b/vesta-service/src/main/resources/spring/vesta-service.xml
@@ -7,6 +7,10 @@
 
        
+               ^M
+       ^M
+^M
+       ^M
                
        

第二十条, revert, reset, checkout的区别。

git revert commit-id:回退到某个commit的点上,这里面回退的只是本地库的代码,工作区和索引并不变化,而且,revert动作会作为一个历史提交到库中,所有的历史都保存。

reset --hard commit-id: 把head指针回退,删除回退过的那些历史,并且改变本地库,索引和工作区的代码。
reset --mixed commit-id: 把head指针回退,删除回退过的那些历史,并且改变本地库,索引的代码。
reset --soft commit-id: 把head指针回退,删除回退过的那些历史,并且改变本地库的代码。

git checkout index.html: 用HEAD上最后一次的提交的文件覆盖工作区和索引文件。

第二十一条, 理解FastFoward。
点击查看文件

参考文章

http://longair.net/blog/2009/04/16/git-fetch-and-merge/

http://www.derekgourlay.com/archives/428
http://stackoverflow.com/questions/3329943/git-branch-fork-fetch-merge-rebase-and-clone-what-are-the-differences
http://blog.mikepearce.net/2010/05/18/the-difference-between-git-pull-git-fetch-and-git-clone-and-git-rebase/
http://stackoverflow.com/questions/1783405/checkout-remote-git-branch

参考资料
Git常用命令