一、获得GIT仓库
有两种获得GIT仓库的方法,一是在需要用GIT管理的项目的根目录执行:
git init
执行后可以看到,仅仅在项目目录多出了一个.git目录,关于版本等的所有信息都在这个目录里面。
另一种方式是克隆远程目录,由于是将远程服务器上的仓库完全镜像一份至本地,而不是取某一个特定版本,所以用clone而不是checkout:
git clone
二、GIT中版本的保存
记录版本信息的方式主要有两种:
- 记录文件每个版本的快照
- 记录文件每个版本之间的差异
GIT采用第一种方式。GIT不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变,若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方法就是用SHA-1算法计算文件的校验和。
三、文件状态
GIT仓库所在的目录称为工作目录,这个很好理解,我们的工程就在这里,工作时也是在这里做修改。
在工作目录中的文件被分为两种状态,一种是已跟踪状态(tracked),另一种是未跟踪状态(untracked)。只有处于已跟踪状态的文件才被纳入GIT的版本控制。
当我们往工作目录添加一个文件的时候,这个文件默认是未跟踪状态的。用以下命令可以跟踪文件:
git add
GIT的三个工作区域:本地数据(仓库)目录,工作目录,暂存区,如下图所示:
git directory就是我们的本地仓库.git目录,里面保存了所有的版本信息等内容。
working driectory,工作目录,就是我们的工作目录,其中包括未跟踪文件及已跟踪文件,而已跟踪文件都是从git directory取出来的文件的某一个版本或新跟踪的文件。
staging area,暂存区,不对应一个具体目录,其时只是git directory中的一个特殊文件。
当我们修改了一些文件后,要将其放入暂存区然后才能提交,每次提交时其实都是提交暂存区的文件到git仓库,然后清除暂存区。而checkout某一版本时,这一版本的文件就从git仓库取出来放到了我们的工作目录。
使用如下命令可查询当前文件状态
git status
暂存文件
git add file A //暂存文件A git add . //暂存当前目录下所有文件
取消暂存文件
git reset HEAD File
如修改了文件,想恢复
git checkout -- File
四、查看文件修改后的差异
git diff
"git diff"显示的是文件修改后还没有暂存起来的内容,那如果要比较暂存区的文件与之前已经提交过的文件呢,可以用以下命令:
git diff --cached
五、忽略一些文件
如果有一些部件我们不想纳入版本控制,也不想在每次"git status"时看到这些文件的提示,或者很多时候我们为了方便会使用"git add ."添加所有修改的文件,这时就会添加上一些我们不想添加的文件,怎么忽略这些文件呢?
GIT当然提供了方法,只需在主目录下建立".gitignore"文件,此文件有如下规则:
- 所有以#开头的行会被忽略
- 可以使用glob模式匹配
- 匹配模式后跟反斜杠(/)表示要忽略的是目录
- 如果不要忽略某模式的文件在模式前加"!"
比如:
# 此为注释 – 将被 Git 忽略
*.a # 忽略所有 .a 结尾的文件
!lib.a # 但 lib.a 除外
/TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
六、移除文件
如果提交暂存区后,本地删除了一些文件,这些文件的移除是无法提交到暂存区的。这时候就可以用到命令:
git rm
如果我们之前不是通过"git rm"删除了很多文件呢?比如说通过patch或者通过GUI,如果这些文件命名没有规则,一个一个地执行"git rm"会搞死人的,这时可以用以下命令:
git rm $(git ls-files --deleted)
七、移动文件(同移除文件)
git mv old_name new_name
这个命令等效于
mv old_name new_name
git rm old_name
git add new_name
八、储藏-Stashing
遇到情况:①在工作分支上工作进行到一半,突然有其他紧急的任务,需要切换分支;②在工作分支上工作进行到一半,需要从远程库中pull新的代码,而代码很可能和当前工作目录中代码存在冲突
可以执行
git stash
这时你会发现你的工作目录变得很干净了,就可以随意切分支进行其他事情的处理了。
可以通过如下命令查看所有stash列表
git stash list
当紧急事情处理完了,需要重新回来这里进行原来的工作时,只需把Stash区域的内容取出来应用到当前工作目录就行,命令就是
git stash apply
git stash apply之后再git stash list会发现,apply后的stash还在stash列表中,如果要将其从stash列表中删除可以用
git stash drop
丢弃这个stash,stash的命令参数都可选择指定stash名字,否则就是最新的stash。
一般情况下apply stash后应该就可以把它从stash列表删除了,先apply再drop还是比较繁琐的,使用以下一条命令就可以同时完成这两个操作
git stash pop
九、提交
git commit
如果我们想跳过暂存区直接提交修改的文件,可以使用"-a"参数,但要慎重,别一不小心提交了不想提交的文件
git commit -a
如果需要快捷地填写提交说明可使用"-m"参数
git commit -m 'commit message'
修订提交
如果我们提交过后发现有个文件改错了,或者只是想修改提交说明,这时可以对相应文件做出修改,将修改过的文件通过"git add"添加到暂存区,然后执行以下命令:
git commit --amend
然后修改提交说明覆盖上次提交,但只能重写最后一次提交。
重排提交
通过衍合(rebase)可以修改多个提交的说明,并可以重排提交历史,拆分、合并提交,关于rebase在讲到分支时再说,这里先看一下重排提交。
假设我们的提交历史是这样的:
如果我们想重排最后两个提交的提交历史,可以借助交互式rebase命令:
git rebase -i HEAD~2 或 git rebase -i 3366e1123010e7d67620ff86040a061ae76de0c8
HEAD~2表示倒数第三个提交,这条命令要指定要重排的最旧的提交的父提交,此处要重排Second commit与Third commit,所以要指定Initial commit的Commit ID。如图所示:
注释部分详细说明了每个选项的作用,如果我们想交互这两个提交,只需把开头的这两行交换下位置就OK了,交换位置后保存,然后看下提交历史:
可以看到提交历史已经变了,而且最新的两个提交的Commit ID变了,如果这些提交已经push到了远程服务器,就不要用这个命令了。
十、PUSH到远程库
git push命令用于将本地分支的更新,推送到远程主机。它的格式与git pull命令相仿。
$ git push <远程主机名> <本地分支名>:<远程分支名>
注意,分支推送顺序的写法是<来源地>:<目的地>,所以git pull是<远程分支>:<本地分支>,而git push是<本地分支>:<远程分支>。
如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。
$ git push origin master
上面命令表示,将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。
如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
$ git push origin :master # 等同于 $ git push origin --delete master
上面命令表示删除origin主机的master分支。
如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。
$ git push origin
上面命令表示,将当前分支推送到origin主机的对应分支。
如果当前分支只有一个追踪分支,那么主机名都可以省略。
$ git push
如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git push。
$ git push -u origin master
上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。
不带任何参数的git push,默认只推送当前分支,这叫做simple方式。此外,还有一种matching方式,会推送所有有对应的远程分支的本地分支。Git 2.0版本之前,默认采用matching方法,现在改为默认采用simple方式。如果要修改这个设置,可以采用git config命令。
$ git config --global push.default matching # 或者 $ git config --global push.default simple
还有一种情况,就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要使用–all选项。
$ git push --all origin
上面命令表示,将所有本地分支都推送到origin主机。
如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用–force选项。
$ git push --force origin
上面命令使用–force选项,结果导致在远程主机产生一个”非直进式”的合并(non-fast-forward merge)。除非你很确定要这样做,否则应该尽量避免使用–force选项。
最后,git push不会推送标签(tag),除非使用–tags选项。
$ git push origin --tags
来源:
http://www.open-open.com/lib/view/open1405048177091.html
http://www.yiibai.com/git/git_push.html#