git笔记
基本使用
git的基本命令
- 安装:sudo apt-get install git git-uid
init
: git init(工作目录运行,会生成一个.git目录,里面会存放索引数据)add
: 将文件添加到暂存区git add
: 添加文件git add .
: 添加所有
commit
: 提交到版本库,一般调用add后只是在暂存区,只有调用commit才会提交到git版本库git commit -m "comment"
:git commit -a
: 提交所有git commit --amend
: 可以重新提交上一次commit,这在上一次提交遗漏了某些文件 时非常有用.
- clone: git clone 只要有.git目录,那么就可以调用该命令来得到git管理的 所有文件 eg: git clone
test.git dest\_dir/ git—->dest\_dir git clone 账户@IP:工作树路径 你的目录
远程github - pull: git pull(将远程分支拉到本地,然后和本地分支合并)
- push: git push(将本地分支推送远程仓库)
branch
: 创建分支或者查看有哪些分支git branch
: 查看有哪些分支git branch <branch>
创建分支git branch -d <branch>
删除分支,如果有commit没有合并,那么会拒绝删除git branch -D <branch>
: 和上一个类似,但是会强制删除
merge
:将制定分支与当前分支合并(git merge TmpBranch 将TmpBranch与当前分支合并)checkout
:切换到分支, tag或者撤销工作目录的修改git checkout <branch/tag>
: 切换到分支或者taggit checkout -- <file>
: 撤销工作目录<file>的修改,实际上就是用暂存区的文件 替换工作目录
diff
: 比较工作区与暂存区或者暂存区与版本库的差异git diff
:工作区与暂存区的diffgit diff --staged
: 暂存区与版本库的diff
reset
:重置,<commit>
如果不指定那么就为HEAD
,可以使用HEAD^/HEAD~1
(父 提交),HEAD^^/HEAD~2
(父父提交)等类似的语法指定相对于HEAD的偏移.git reset <commit> <file>
: 不修改引用,但是撤销对文件的暂存,也就是用版本库
中的文件替换暂存区中的文件, 工作目录的文件不会变动git reset --hard <commit>
: 将引用设置为commit, 同时用commit的文件替换暂存
区和工作目录. 慎用.git reset --soft <commit>
: 只将引用设置为commit, 不修改暂存区和工作目录git reset --mixed <commit>
: 将引用设置为commit,同时替换暂存区,但是不替换 工作目录
blame
: 用来确定文件的每一行都是谁修改的
git一般的工作过程是:
- git pull(将远程分支与本地分支合并)
- git log(查看其他成员的更改)
- git branch (建一个本地分支)
- git checkout(进入本地分支)
- 在该本地分支上进行修改
- git checkout(回到主分支)
- git merge (将分支上所做的工作合并到主分支)
- git branch -d (删除今天创建的分支)
- git pull(将远程仓库合并到本地仓库,很重要,因为今天可能别人修改了远程仓库)
- git push (将本地仓库合并到远程仓库)
git的原理
工作区(work tree)
就是你本地的工作目录树
- git add :将工作区的文件提交到暂存区,暂存区的目录树会更新
git的暂存区(index)
暂存区可以看作一个目录树,暂存区的目录树和版本库的目录树是不同的,.git目录有一个index文件,这个文件包含了
git所管理的目录中所有文件的大小以及修改时间,每一次你调用git status或者git
diff这类命令时,git都会比较工作
区的文件与该index文件中记录的文件的差异,如果发现文件的大小已经改变,那么工作区的文件肯定已经改变,如果发
现文件的修改时间已改变,那么git会读取工作区中的文件与暂存区的文件的内容进行比较,如果内容相同,那么git会修
改index文件的相应条目的文件时间(因为虽然时间改变了,但文件内容没有改变),这就是基本的工作流程了
- git commit: 将暂存区的文件提交到版本库
- git reset HEAD : 暂存区的目录树会被当前分支的版本库目录树替换,所以任何未提交的更新都会丢弃,但工作区不受 影响
- git checkout 或者 git checkout – <file>
:用暂存区的全部或者部分文件来替换工作区的文件,所以这个操作会清
除没有添加到暂存区的工作区改动, 危险操作 - git checkout HEAD 或者 git checkout HEAD <file> :
用HEAD指向的版本库分支的全部或者部分文件来替换暂存区与
工作区的文件,所以这个操作会清除所有未提交的暂存区与工作区改动. 危险操作 - git rm –cached <file> : 直接删除暂存区中的文件,工作区不受影响
- git rm <file> : 会删除工作区与暂存区的指定文件
版本库
由git管理的分支代码的目录树,比如master分支,以及其它你自己创建的分支,当然操作时一般都只是当前分支的目录树
git diff
- git diff : 工作区与暂存区比较
- git diff HEAD : 工作区与HEAD比较
- git diff –cached : 暂存区与HEAD比较
HEAD, master
HEAD(.git/HEAD)实际是一个指针,指向的是.git/refs/heads/branch-name文件,
branch-name可以是master或者你自己创 建的分支名,该文件实际指向的是该分支的最新的一次commit,
如果当前是master分支,那么这几个文件的内容应该是这 样:
- .git/HEAD : “.git/refs/heads/master” 如果用git
checkout改变分支,那么master会变成相应的分支名,所以HEAD可
以认为一直指向当前分支 - .git/refs/heads/master: 235fd887b9f85d44ce94e8d733b8814509c1d4e8
(master分支最新一次提交的id),通过 git reset
–[hard|soft|mixed]可以重置该文件到指定的commit
id,那么在你指定的commit id之后的提交就都会丢失.
git github
- git remote add remoteName remoteUrl eg: git remote add origin
git@github.com:youName/github-example.git
只第一次新建了仓库时才需要运行,实际上是将本地的仓库与远程的仓库关联起来
如果出错可以使用命令 git remote rm origin - git push origin master(将本地的仓库推送到远端)
如果报错那么极有可能是远端仓库被别人提交过了,所以要先pull,与本地合并然后在提交
git pull origin master - git pull -u origin master origin是远程分支的名字,master是本地分支的名字
- 子模块
- 添加子模块:
git submodule add repo-url local-path
- clone子模块:
git clone --recursive repo-url
,
如果不指定recursive,那么clone后需要初始化git submodule update --init --recursive
- 更新:
git submodule update
- 删除: ubmodule的删除稍微麻烦点:首先,要在“.gitmodules”文件中删除相应配置信息。然后,执行“git rm
–cached ”命令将子模块所在的文件从git中删除。
- 添加子模块:
- fork后合并原仓库的改变 情景如下:我在github
fork一个仓库(https://github.com/purcell/emacs.d.git )到我的的账户
(https://github.com/yuyang0/emacs.d.git )然后我将这个fork仓库clone到本地,现在
我要合并原仓库的改变。。 first: git remote add purcell
https://github.com/purcell/emacs.d.git next: git pull purcell
master (git fetch purcell, git merge purcell/master) next: git push
origin master
gitignore syntax
“#“ : 注释
! : 取反,即匹配模式的文件不忽略
/ : /结尾被当作目录,该目录的所有文件忽略
/ : /开头则只忽略工作树根目录开始匹配eg:core/TODO与/core/TODO不
同,前者只要文件路径包含core/TODO(如doc/core/TODO)即匹配,
而后者则只匹配工作树根目录下的core文件夹的TODO文件glob模式:glob模式不同于正则表达式,等同于shell模式下的方式
*:匹配任意字符
?: 匹配任意单个字符
[abcd]: 匹配a b c d中的一个
[a-z]: 匹配a-z之间的一个字符
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!