Git快速参考
===============
===============
常用命令一览
------------------------
* git clone
* git status
* git add
* git commit
* git pull
* git push
* git mv
* git rm
* git log
* git diff
------------------------
* git clone
* git status
* git add
* git commit
* git pull
* git push
* git mv
* git rm
* git log
* git diff
Git和Svn的几个重要区别
------------------------
和svn比起来,Git的提交代码多了2个重要步骤:远程提交和暂存区。
------------------------
和svn比起来,Git的提交代码多了2个重要步骤:远程提交和暂存区。
远程提交。Git是一个分布式的源码管理系统,不像SVN有中心服务器的概念,每个人的版本库都可以被另一个人获取和更新当中心服务器使用.在我们目前的项目中,文件服务器上的Git库被指定为"中心服务器".
如果你想提交新代码到文件服务器,需要2步,流程如下:提交到本地 --- 提交到文件服务器.(具体命令下文会讲到.)
svn则只需要一步:直接提交到远程服务器.
Git多出的一步,可供开发者保存不想公开的代码,如,暂时还不成熟的代码.
暂存区。Git另一个强大之处是它有一块区域专门存放"修改了但还未提交到本地版本库"的代码。如:修改了3个文件,一个未完成,只能提交2个,这时可以先提交这2个文件到暂存区,再从暂存区正式到本地。
暂存区是Git中很重要的概念,弄清了它,就入门了一半。理解远程提交则是另一半。
这里有篇文章详细的解释了Git的文件状态,包括暂存区:
http://progit.org/book/zh/ch2-2.html
Git基本操作
---------------
---------------
git clone
^^^^^^^^^^^^^^^
获取远程服务器上的代码::
$ git clone git@192.168.1.223:wenku
Cloning into doc...
remote: Counting objects: 54, done.
remote: Compressing objects: 100% (51/51), done.
remote: Total 54 (delta 23), reused 0 (delta 0)
Receiving objects: 100% (54/54), 14.04 KiB, done.
Resolving deltas: 100% (23/23), done.
^^^^^^^^^^^^^^^
获取远程服务器上的代码::
$ git clone git@192.168.1.223:wenku
Cloning into doc...
remote: Counting objects: 54, done.
remote: Compressing objects: 100% (51/51), done.
remote: Total 54 (delta 23), reused 0 (delta 0)
Receiving objects: 100% (54/54), 14.04 KiB, done.
Resolving deltas: 100% (23/23), done.
git status
^^^^^^^^^^^^^^^
查看当前工作区的状态::
^^^^^^^^^^^^^^^
查看当前工作区的状态::
$ git status
# On branch master
# Changed but not updated: #文件被修改,但还未提交到版本库
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: index.rst
#
# Untracked files: #新文件,没有提交过
# (use "git add <file>..." to include in what will be committed)
#
# source/git.rst
no changes added to commit (use "git add" and/or "git commit -a")
# On branch master
# Changed but not updated: #文件被修改,但还未提交到版本库
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: index.rst
#
# Untracked files: #新文件,没有提交过
# (use "git add <file>..." to include in what will be committed)
#
# source/git.rst
no changes added to commit (use "git add" and/or "git commit -a")
Untracked files 没有跟踪过的文件,即从未提交过的文件。
Changed but not updated 修改但还没有提交
这2个文件都还未进暂存区
git add
^^^^^^^^^^^^^^^
将文件添加进暂存区::
^^^^^^^^^^^^^^^
将文件添加进暂存区::
$ git add source/git.rst
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: source/git.rst
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: index.rst
#
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: source/git.rst
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: index.rst
#
source/git.rst 已添加进暂存区,只差提交(git commit)这一步就进入本地的版本库了。
index.rst 虽然被改动,但还未进暂存区,这个文件如需同批提交到本地的库,提交前需要如法炮制添加进暂存区。如果下次提交进本地库,则这里不用加到暂存区。
这也是git强大处之一 --- 利用暂存区,灵活控制需要提交的文件。
git commit
^^^^^^^^^^^^^^^
将暂存区的文件提交进本地版本库::
^^^^^^^^^^^^^^^
将暂存区的文件提交进本地版本库::
$ git commit -m '新增git快速参考'
[master d1eed2a] 新增git快速参考
2 files changed, 76 insertions(+), 0 deletions(-)
create mode 100644 source/git.rst
[master d1eed2a] 新增git快速参考
2 files changed, 76 insertions(+), 0 deletions(-)
create mode 100644 source/git.rst
提交以后暂存区的文件都进了本地版本库,此时暂存区是空的。
git pull
^^^^^^^^^^^^^^^
更新远程服务器上的最新代码到本地.
^^^^^^^^^^^^^^^
更新远程服务器上的最新代码到本地.
提交本地代码到远程服务器前,必须更新至最新版本(如果其它人更新了远程版本库,git会警告并禁止提交)::
$ git pull
git@192.168.1.223:wenku
From 192.168.1.223:wenku
* branch HEAD -> FETCH_HEAD
Already up-to-date.
From 192.168.1.223:wenku
* branch HEAD -> FETCH_HEAD
Already up-to-date.
这代表本地库已是最新的版本
git push
^^^^^^^^^^^^^^^
本地代码提交到远程::
^^^^^^^^^^^^^^^
本地代码提交到远程::
$ git push
Counting objects: 8, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 1.86 KiB, done.
Total 5 (delta 2), reused 0 (delta 0)
To git@192.168.1.223:wenku
d4d7249..d1eed2a master -> master
Counting objects: 8, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 1.86 KiB, done.
Total 5 (delta 2), reused 0 (delta 0)
To git@192.168.1.223:wenku
d4d7249..d1eed2a master -> master
git rm
^^^^^^^^^^^^^^^
删除文件或目录::
^^^^^^^^^^^^^^^
删除文件或目录::
git rm file
git rm dir/
git rm dir/
git mv
^^^^^^^^^^^^^^^
重命名或者移动文件(或者目录)::
^^^^^^^^^^^^^^^
重命名或者移动文件(或者目录)::
git mv file1 file2
git mv dir1/ dir2/
git mv dir1/ dir2/
撤销修改
---------------
---------------
修改上一次提交
^^^^^^^^^^^^^^^^
::
^^^^^^^^^^^^^^^^
::
git commit --amend
取消已经暂存的文件
^^^^^^^^^^^^^^^^^^^
::
git reset HEAD FILE
取消对文件的修改(未进入暂存区)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
git checkout --FILE
分支操作
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
查看分支::
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
查看分支::
git branch
创建分支::
git branch 分支名
删除分支::
git branch -d 分支名
切换分支(切换分支前需将当前分支下的修改commit)::
git checkout 分支名
git checkout -b 分支名 #新建分支并切换
合并分支::
git merge 分支名
有 人把 Git 的分支模型称为“必杀技特性”,而正是因为它,将 Git 从版本控制系统家族里区分出来。Git 鼓励在工作流程中频繁使用分支与合并,哪怕一天之内进行许多次都没有关系。理解分支的概念并熟练运用后,你才会意识到为什么 Git 是一个如此强大而独特的工具,并从此真正改变你的开发方式。
其它使用操作
---------------
git log
^^^^^^^^^^^^^^^
查看提交日志::
git log
git diff
^^^^^^^^^^^^^^^
显示本次改动::
^^^^^^^^^^^^^^^
显示本次改动::
git diff
Git高级操作
---------------
---------------
git config
^^^^^^^^^^^^^^^
Git 命令别名::
^^^^^^^^^^^^^^^
Git 命令别名::
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
Git中的着色::
$ git config --global color.ui true
test库git操作示范
------------------------
上面我们将了git的一系列常规指令。下面我们以test库为例,讲过整个开发过程中使用的git操作。同时希望读者能跟着实际操作一遍,以便加深印象。
首先将test库从文件服务器上clone一份到开发环境下。
$ cd ~/www #一般情况下我们的web代码都放在www目录下
$ git clone git:192.168.1.223:test #文件服务器ip为192.168.1.223,库名test
$ cd test #clone完毕后,会出现test代码目录。进入该目录,后面的操作都在此目录下
$ git checkout --track origin/develop #我们的开发都在develop分支下,因此要跟踪文件服务器上的develop分支,并切换到develop分支。可以通过git branch指令查看当前分支情况。
$ git clone git:192.168.1.223:test #文件服务器ip为192.168.1.223,库名test
$ cd test #clone完毕后,会出现test代码目录。进入该目录,后面的操作都在此目录下
$ git checkout --track origin/develop #我们的开发都在develop分支下,因此要跟踪文件服务器上的develop分支,并切换到develop分支。可以通过git branch指令查看当前分支情况。
此时,我们的代码以全部从远程的文件服务器上拷贝下来。接下去进入日常的开发或维护工作。
假设现在你接到一个任务。任务编号为157,任务内容为完善README文件。那么我们进行如下操作:
$ cd ~/www/test #进入test库工作目录
$ git checkout -b iss157 #为任务157创建一个独立的分支,并在iss157分支下开发。
$ vim README #根据任务内容描述,去完善README。此处我们用vim编辑器编辑README文件,当然你也可以在windows下,通过samba共享,来修改README文件。
$ git checkout -b iss157 #为任务157创建一个独立的分支,并在iss157分支下开发。
$ vim README #根据任务内容描述,去完善README。此处我们用vim编辑器编辑README文件,当然你也可以在windows下,通过samba共享,来修改README文件。
假设一天的工作已结束,我们要将还为完成的README文件先入库一次。那么我们进行如下操作:
$ git status #查阅当前状态,此时git会列出修改过的,未跟踪的,或已暂存的文件列表
# On branch iss157
# 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
#
no changes added to commit (use "git add" and/or "git commit -a")
# 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
#
no changes added to commit (use "git add" and/or "git commit -a")
在状态中,我们可以了解到,有一个README文件修改过,如果想要提交文件,首先使用git add <file>指令(use "git add <file>..." to update what will be committed)。
$ git add README #添加README文件。小技巧:如果在putty中操作,可以用鼠标双击README,然后鼠标右击,粘帖到指令中。如果有多个文件,可以用空格分隔。
$ git status #再次查看状态
$ git status #再次查看状态
# On branch iss157
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README
#
此 时,状态显示README已进入将要提交的文件列表中(Changes to be committed)。如果想取消add,可以使用git reset HEAD <file> 指令 (use "git reset HEAD <file>..." to unstage)
$ git commit -m '测试' #提交代码到本地库中,此处的测试为注释信息
$ git status
# On branch iss157
nothing to commit (working directory clean)
nothing to commit (working directory clean)
提交完成后的状态
$ git log 查看提交记录
commit 484e49709d8c2b45d3050c92560c4b3c04cf5b04
Author: zhangyuan < zhangyuan@socialvoice.cn>
Date: Thu Feb 23 11:16:35 2012 +0800
Author: zhangyuan < zhangyuan@socialvoice.cn>
Date: Thu Feb 23 11:16:35 2012 +0800
测试
commit c287961e015d07a149e82a7b8e44811649b5125f
Author: zhangyuan < zhangyuan@socialvoice.cn>
Date: Wed Feb 22 18:15:41 2012 +0800
Author: zhangyuan < zhangyuan@socialvoice.cn>
Date: Wed Feb 22 18:15:41 2012 +0800
t
经过多次的修改和commit后,README进入稳定状态。此时我们可以将iss157分支合并到develop中。
$ git checkout develop #切换到develop分支。可以通过git branch来查看当前分支信息
$ git merge iss157 #合并分支。此时README文件以合并到develop分支下。
$ git branch -d iss157 #iss157分支以无用了,我们将其删除。
$ git branch #查看分支情况,你可以发现iss157分支不在了。
$ git push #将当前develop同步到远程分支。
$ git merge iss157 #合并分支。此时README文件以合并到develop分支下。
$ git branch -d iss157 #iss157分支以无用了,我们将其删除。
$ git branch #查看分支情况,你可以发现iss157分支不在了。
$ git push #将当前develop同步到远程分支。
整个README维护完毕。
通 过上文,我想你已对git在日常代码维护中的操作步骤有一个初步的了解。但有时操作并不会那么顺利。特别在多人协作开发过程中,经常会碰到多人同时修改同 一文件的情况,大部分情况,git能自动将多人修改的结果进行合并。但有时还是需要手动进行。我们在此将模拟此类环境,讲解git手动合并的过程。
首先我们来创建模拟环境。为了演示简单,我们此处不使用分支来开发,直接在develop上进行修改,(注:日常开发中,我们还是需要使用分支,以使版本维护更清晰)。
$ cd ~/www/test
$ git checkout develop
$ echo 'aaa' > demo1.html #创建文件demo1.html,并将aaa字符写入demo1.html
$ git add demo1.html
$ git commit -m 'demo1 aaa'
$ git push
$ git checkout develop
$ echo 'aaa' > demo1.html #创建文件demo1.html,并将aaa字符写入demo1.html
$ git add demo1.html
$ git commit -m 'demo1 aaa'
$ git push
此时我们创建并入库了一个demo1.html文件。demo1.html在远程库和本地库内容都为aaa
我们现模拟第二个用户来clone此文件
$ mkdir ~/www/programmer2
$ cd ~/www/programmer2 #创建一个新目录,作为程序员2的工作目录
$ git clone git@192.168.1.223:test #clone test库
$ cd ~/www/programmer2/test
$ git checkout --track origin/develop
$ echo 'aba' > demo1.html #将demo1.html文件的'aaa'字符改为'aba'
$ git add demo1.html
$ git commit -m 'demo1 aba'
$ git push #将文件提交,并同步的文件服务器上。
$ cd ~/www/programmer2 #创建一个新目录,作为程序员2的工作目录
$ git clone git@192.168.1.223:test #clone test库
$ cd ~/www/programmer2/test
$ git checkout --track origin/develop
$ echo 'aba' > demo1.html #将demo1.html文件的'aaa'字符改为'aba'
$ git add demo1.html
$ git commit -m 'demo1 aba'
$ git push #将文件提交,并同步的文件服务器上。
此时demo1.html文件在远程库中的内容为 aba
我们在切换到~/www/test。
现在在~/www/test/demo1.html 的内容为aaa, 而远程库(文件服务器)上由于programmer2将其内容已改为aba。
$ cd ~/www/test
$ echo 'aca' > demo1.html #我们将文件内容改成了aca
$ git add demo1.html
$ git commit -m 'demo1 aca'
$ git push
To git@192.168.1.223:test
! [rejected] develop -> develop (non-fast-forward)
error: failed to push some refs to 'git@192.168.1.223:test'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.
$ echo 'aca' > demo1.html #我们将文件内容改成了aca
$ git add demo1.html
$ git commit -m 'demo1 aca'
$ git push
To git@192.168.1.223:test
! [rejected] develop -> develop (non-fast-forward)
error: failed to push some refs to 'git@192.168.1.223:test'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.
push失败,原因在于,远程库的文件被programmer2修改了,版本较新,本地库的版本较旧。
从提示信息中我们得知,我们需要先git pull,将远程库上的文件同步下来,进行一个合并。
$ git pull
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From 192.168.1.223:test
bf0c63a..c4295b9 develop -> origin/develop
Auto-merging demo1.html
CONFLICT (content): Merge conflict in demo1.html
Automatic merge failed; fix conflicts and then commit the result.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From 192.168.1.223:test
bf0c63a..c4295b9 develop -> origin/develop
Auto-merging demo1.html
CONFLICT (content): Merge conflict in demo1.html
Automatic merge failed; fix conflicts and then commit the result.
从pull后的信息中,我们可以得知,git先试图合并demo1.html的两次修改,大部分情况下git能自动合并。在我们的示范中,由于改的是同一块内容,所以合并失败,此时我们得手动合并文件
$ vim demo1.html
demo1.html的内容如下:
<<<<<<< HEAD
aca
=======
aba
>>>>>>> c4295b91e65092349f368ef83b6528d7a1d118e8
aca
=======
aba
>>>>>>> c4295b91e65092349f368ef83b6528d7a1d118e8
在git无法自动完成合并时,和svn一样,在文件中会同时列出,两个版本的内容。如demo1.html中aca为最新版本,aba为老版本。
我们修改文件,留正确的结果。此处我们想修改为aca,因此修改内容为aca。操作如下:
删除 <<<<<<< HEAD
保留 aca
删除 =======
删除 aba
删除 >>>>>>> c4295b91e65092349f368ef83b6528d7a1d118e8
保留 aca
删除 =======
删除 aba
删除 >>>>>>> c4295b91e65092349f368ef83b6528d7a1d118e8
修改文件后,需要将正确的文件,再此提交。操作如下:
$ git status
$ git status
# On branch develop
# Your branch and 'origin/develop' have diverged,
# and have 1 and 1 different commit(s) each, respectively.
#
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: demo1.html
#
no changes added to commit (use "git add" and/or "git commit -a")
# Your branch and 'origin/develop' have diverged,
# and have 1 and 1 different commit(s) each, respectively.
#
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: demo1.html
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git add demo1.html
$ git commit -m 'merge demo1'
$ git push
完毕
转载于:https://blog.51cto.com/jerry1204/795396