一、获得GIT仓库
git init
会生成.git目录
git init --bare
不会生成.git目录,不允许在里面直接进行git操作
一般用于远端仓库生成裸仓库
git clone <url>
#clone一个远程仓库时会自动在本地生成一个名叫original的远程仓库,下载远程仓库的所有数据,并新建一个指向它的分支original/master,但这个分支我们是无法修改
二、GIT文件操作
在工作目录中的文件被分为两种状态,一种是已跟踪状态(tracked),另一种是未跟踪状态(untracked)。只有处于已跟踪状态的文件才被纳入GIT的版本控制。
GIT的三个工作区域:本地数据(仓库)目录,工作目录,暂存区
.git目录
里面保存了所有的版本信息等内容
staging area,暂存区
不对应一个具体目录,其时只是.git 中的一个特殊文件。
当我们修改了一些文件后,要将其放入暂存区然后才能提交,每次提交时其实都是提交暂存区的文件到git仓库,然后清除暂存区。
working driectory,工作目录
就是我们的工作目录,其中包括未跟踪文件及已跟踪文件
# 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: lichee/linux-3.4/drivers/misc/FM34.c
# modified: lichee/linux-3.4/sound/soc/sunxi/audiocodec/sun8iw5_sndcodec.c
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# testfilea
no changes added to commit (use "git add" and/or "git commit -a")
1. 跟踪文件
加入到git管理中
git add <file>
git rm --cached <file> # 取消不会删除文件
git rm -f <file> #会删除文件
2.文件暂存
git add <file>... #就可以暂存文件
git reset HEAD <file>... #取消暂存文件是
git checkout -- <file>... #用stage的文件覆盖现在modify的文件
git diff --staged # 查看文件修改后的差异
3. gitignore
*.a # 忽略所有 .a 结尾的文件
!lib.a # 但 lib.a 除外
/filename # 仅仅忽略项目根目录下的 filename 文件,不包括 subdir/filename
build/ # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:
git rm -r --cached .
git add .
git commit
4.储藏-Stashing
使用场景:
使用git的时候,我们往往使用branch解决任务切换问题,例如,我们往往会建一个自己的分支去修改和调试代码, 如果别人或者自己发现原有的分支上有个不得不修改的bug,我们往往会把完成一半的代码 commit提交到本地仓库,然后切换分支去修改bug,改好之后再切换回来。这样的话往往log上会有大量不必要的记录。其实如果我们不想提交完成一半或者不完善的代码,但是却不得不去修改一个紧急Bug,那么使用'git stash'就可以将你当前未提交到本地(和服务器)的代码推入到Git的栈中,这时候你的工作区间和上一次提交的内容是完全一样的,所以你可以放心的修 Bug,等到修完Bug,提交到服务器上后,再使用'git stash apply'将以前一半的工作应用回来。
git stash apply #将当前分支的最后一次缓存的内容释放出来,但是刚才的记录还存在list中
git stash pop #将当前分支的最后一次缓存的内容释放出来,但是刚才的记录不存在list中
git stash drop <stash@{id}> #删除stash。
git stash clear #清除所有stash,
5.重排提交 rebase
通过衍合(rebase)可以修改多个提交的说明,并可以重排提交历史,拆分、合并提交。
HEAD表示当前所在的提交
^ 表示指定提交的父提交,这个提交可能由多个交提交,之后跟上数字表示第几个父提交,不跟数字等同于1。
n相当于n个^,比如3=^^^,表示第一个父提交的第一个父提交的第一个父提交。
git rebase -i HEAD~2 或 git rebase -i 3366e1123010e7d67620ff86040a061ae76de0c8
删除
如果要删除某个提交,只需要删除相应的行就可以了,
修改说明
而要修改某个提交的提交说明的话,只需要把相应行的pick改为reward。
合并
pick改为squash就可以把这个提交全并到它上一行的提交中
拆分
这时要把pick改为edit,这样Git在处理到这个提交时会停下来,此时我们就可以进行相应的修改并多次提交来拆分
6. 撤销提交
如果某个提交已经Push到远程仓库 , 用 git revert <commit-id>
如果撤销本地提交
git reset [options] <commit>
--soft: 只改变HEAD的State,不更改工作区与暂存区的内容
--mixed(默认): 撤销暂存区的修改,暂存区的修改会转移到工作区
--hard: 撤销工作区与暂存区的修改
git reset --soft HEAD^ #回到add之前, 还可以继续修改 commit
git reset --hard HEAD^
#恢复
git reflog #会显示SHA
git reset <SHA>
7. cherry-pick , tag
git cherry-pick commit1
git tag -a V03
9. 远程提交
git push origin master
origin指定了你要push到哪个remote
master其实是一个“refspec”,正常的“refspec”的形式为”+<src>:<dst>”,冒号前表示local branch的名字,冒号后表示remote repository下 branch的名字。
注意,如果你省略了<dst>,git就认为你想push到remote repository下和local branch相同名字的branch。
$git push origin master:refs/for/mybranch (在local repository中找到名字为master的branch,用他去更新remote repository下面名字为mybranch的branch)
$git push origin HEAD:refs/for/mybranch (HEAD指向当前工作的branch,master不一定指向当前工作的branch,所以我觉得用HEAD还比master好些)
git fetch
git rebase origin/master # 同步远端的代码和本地
git push origin master
patch两种方法
git diff
git diff > 1.patch
git apply 1.patch
git apply --check 查看补丁是否能够干净顺利地应用到当前分支中
diff生成的Patch兼容性强
format-patch
git format-patch -M master 0001-Fix1.patch
git am 0001-Fix1.patch #am会给出提示,并协助你完成打补丁工作
git format-patch的-M选项表示这个patch要和那个分支比对
。