用这个要当心,它会把那个commit之后的commit全部删除。一个好的办法是:先建立一个临时的分支,然后再git-reset,再git-rebase,最后再删除临时的分支。 详细可以看这里。
$ git add -p // 为你做的每次修改,Git将为你展示变动的代码,并询问该变动是否应是下一次提交的一部分。回答“y”或者“n”。也有其他选项,比如延迟决定:键入“?”来学习更多。
git add <path>表示 add to index only files created or modified and not those deleted
我通常是通过git add <path>的形式把我们<path>添加到索引库中,<path>可以是文件也可以是目录。
git不仅能判断出<path>中,修改(不包括已删除)的文件,还能判断出新添的文件,并把它们的信息添加到索引库中。
三、git add -u
git add -u 表示 add to index only files modified or deleted and not those created
git add -u [<path>]: 把<path>中所有tracked文件中被修改过或已删除文件的信息添加到索引库。它不会处理untracted的文件。
省略<path>表示.,即当前目录。
四、git add -A
git add -A: [<path>]表示把<path>中所有tracked文件中被修改过或已删除文件和所有untracted的文件信息添加到索引库。
省略<path>表示.,即当前目录。
五、git add -i
我们可以通过git add -i [<path>]命令查看<path>中被所有修改过或已删除文件但没有提交的文件,
并通过其revert子命令可以查看<path>中所有untracted的文件,同时进入一个子命令系统。
比如:
git add -i
staged unstaged path
1: +0/-0 nothing branch/t.txt
2: +0/-0 nothing branch/t2.txt
3: unchanged +1/-0 readme.txt
*** Commands ***
1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked
5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp
What now>
这里的t.txt和t2.txt表示已经被执行了git add,待提交。即已经添加到索引库中。
readme.txt表示已经处于tracked下,它被修改了,但是还没有被执行了git add。即还没添加到索引库中。
5.1、revert子命令
可以通过git add -i的revert子命令(3: [r]evert)把已经添加到索引库中的文件从索引库中剔除。
(3: [r]evert)表示通过3或r或revert加回车执行该命令。执行该命令后,git会例出索引库中的文件列表.
然后通过数字来选择。输入"1"表示git会例出索引库中的文件列表中的第1个文件。
"1-15"表示git会例出索引库中的文件列表中的第1个文件到第15个文件.回车将执行。
如果我们不输入任何东西,直接回车,将结束revert子命令,返回git add -i的主命令行。
5.2、update子命令
可以通过update子命令(2: [u]pdate)把已经tracked的文件添加到索引库中。其操作和revert子命令类似。
5.3、add untracked子命令
通过add untracked子命令(4: [a]dd untracked)可以把还没被git管理的文件添加到索引库中。其操作和revert子命令类似。
5.4、diff子命令
可以通过diff子命令(6: [d]iff)可以比较索引库中文件和原版本的差异。其操作和revert子命令类似。
5.5、status子命令
status子命令(1: [s]tatus)功能上和git add -i相似
5.6、quit子命令
quit子命令(7: [q]uit)用于退出git add -i命令系统
六、帮助
我们可以通过git add -h命令来看git add命令的帮助文档。
git add -h
usage: git add [options] [--] <filepattern>...
-n, --dry-run dry run
-v, --verbose be verbose
-i, --interactive interactive picking
-p, --patch select hunks interactively
-e, --edit edit current diff and apply
-f, --force allow adding otherwise ignored files
-u, --update update tracked files
-N, --intent-to-add record only the fact that the path will be added later
-A, --all add changes from all tracked and untracked files
--refresh don't add, only refresh the index
--ignore-errors just skip files which cannot be added because of errors
--ignore-missing check if - even missing - files are ignored in dry run
2)分支(branch)操作相关命令
查看本地分支:$
git branch
查看远程分支:$
git branch -r
创建本地分支:$
git branch [name] ----注意新分支创建后不会自动切换为当前分支
切换分支:$
git checkout [name]
创建新分支并立即切换到新分支:$
git checkout -b [name]
删除分支:$
git branch -d [name] ---- -d选项只能删除已经参与了合并的分支,对于未有合并的分支是无法删除的。如果想强制删除一个分支,可以使用-D选项
重命名分支:git branch -m <old_name> <new_name> 改名字 (如果有同名會失敗,改用 -M 可以強制覆蓋)
合并分支:$
git merge [name] ----将名称为[name]的分支与当前分支合并
创建远程分支(本地分支push到远程):$git push origin [name]
删除远程分支:$
git push origin :heads/[name]
我从master分支创建了一个issue5560分支,做了一些修改后,使用git push origin master提交,但是显示的结果却是'Everything up-to-date',发生问题的原因是git push origin master 在没有track远程分支的本地分支中默认提交的master分支,因为master分支默认指向了origin
master 分支,这里要使用git push origin issue5560:master 就可以把issue5560推送到远程的master分支了。
如果想把本地的某个分支test提交到远程仓库,并作为远程仓库的master分支,或者作为另外一个名叫test的分支,那么可以这么做。
$
git push origin test:master // 提交本地test分支作为远程的master分支
$ git push origin test:test // 提交本地test分支作为远程的test分支
如果想删除远程的分支呢?类似于上面,如果:左边的分支为空,那么将删除:右边的远程的分支。
$
git push origin :test // 刚提交到远程的test将被删除,但是本地还会保存的,不用担心
3)版本(tag)操作相关命令
查看版本:$
git tag
创建版本:$
git tag [name]
删除版本:$
git tag -d [name]
查看远程版本:$
git tag -r
创建远程版本(本地版本push到远程):$git push origin [name]
删除远程版本:$
git push origin :refs/tags/[name]
4) 子模块(submodule)相关操作命令
添加子模块:$
git submodule add [url] [path]
如:$
git submodule add
git://github.com/soberh/ui-libs.git src/main/webapp/ui-libs
初始化子模块:$
git submodule init ----只在首次检出仓库时运行一次就行
更新子模块:$
git submodule update ----每次更新或切换分支后都需要运行一下
删除子模块:(分4步走哦)
1)$
git rm --cached [path]
2) 编辑“.gitmodules”文件,将子模块的相关配置节点删除掉
3) 编辑“.git/config”文件,将子模块的相关配置节点删除掉
4) 手动删除子模块残留的目录
5)忽略一些文件、文件夹不提交
在仓库根目录下创建名称为“.gitignore”的文件,写入不需要的文件夹名或文件,每个元素占一行即可,如
target
bin
*.db
关于git删除远程分支
git branch -r -d origin/branch-name
发现只是删除的本地对该远程分支的track,正确的方法应该是这样:
git push origin :branch-name
冒号前面的空格不能少,原理是把一个空分支push到server上,相当于删除该分支。
查看远程仓库:$
git remote -v
添加远程仓库:$
git remote add [name] [url]
删除远程仓库:$
git remote rm [name]
修改远程仓库:$
git remote set-url --push[name][newUrl]
commit
提交修改的代码(只是提交到本地的代码库,不会推送到服务器)
$ git commit -am '修改说明'
如果觉得刚提交的“修改说明”写得不够好,可输入以下命令调整
$ git commit --amend
push
将自上次 push 以来的,本地历次 commit,推送到服务器
结合我们的实际,应该这样写:
$ git push origin master:your-id
其中,master 是本地的分支名;your-id 填你在服务器上的 id,服务器的版本库里会有以你的 id 为名称的分支。
tag
在git中可以为任意其他对象添加tag,包括commit,tree,blob,甚至包括tag自身。git中都是用sha-1标识git对象,这是一个40个字符长度的字符串,不方便记忆,那么可为git对象添加一个tag便于标识不同对象。
添加tag
# git tag tag-name sha-1
$ git tag v1.0 bdc390c2
这样便为bdc390c2的对象添加了一个tag,如果不指定sha-1,会为最近的一个commit对象添加tag
查看tag
使用git tag命令便能查看所有tag
$ git tag
当然可以筛选
$ git tag -l 'v1.*'
删除tag
$ git tag -d <tag-name>
重命名tag
重命名tag有两种方式:
删除原tag,重新添加
git tag -f 强制替换已存在的tag后,再删除原tag
$ git tag -f <new-tag> <old-tag>
$ git tag -d <old-tag>
tag的分类
轻量型标签 轻量型标签直接使用 $ git tag <tag-name> <git-object> 即可创建
标注型(annotated)标签 标注型标签可记录更多的信息,使用 $ git tag -a <tag-name> <git-object> -m ‘tag message’即可创意一个标注性标签
#git cherry-pick 321d76f
这个执行过程git已经执行了一个commit过程。
如果有的时候我们要直接提交怎么办呢?
#git cherry-pick -n 321d76f
通过添加-n参数,git只会将变化提交到缓存中,没有执行commit
待你修改完其它后可以一起commit了
#git commit
git branch -v命令将附加显示最后一次提交相关信息的分支信息
$ git branch -v
# 查看已合并的分支
$ git branch --merge
# 查看未合并的分支
$ git branch --no-merged
ignore
在一个git版本仓库中,有时候很多文件/目录并不需要使用git进行版本维护,那么就可以将这些文件/目录加入.gitignore文件中,
在.gitignore文件中可定义要排除在git版本管理之外的文件/目录,git默认会读取项目目录下的.gitignore文件。
.gitignore使用标准的shell glob模式匹配,shell glob你可以简单地理解为一种特特殊化的正则表达式,其实要比正则表达式简单许多,语法如下:
- 允许使用空行,没有实际语法作用
- # 开头的行视作注释
- ! 开头的模式会覆盖之前的定义,将匹配的对象重新加入跟踪列表
- 以/结尾的模式,git会屏蔽掉该目录及其所有子目录及文件(只屏蔽目录)
- 不以/结尾的模式,git屏蔽同名的文件名及目录(屏蔽目录和同名文件)
- 以/开头的模式,git只会屏蔽项目根目录下的匹配对象
示例:
#.gitignore example
.txt
.gitignore
!readme.txt
exclude/*.txt
该.gitignore中定义的屏蔽规则为:
屏蔽所有的txt文件,但是readme.txt例外;屏蔽所有的.gitignore文件;屏蔽exclude目录下的所有txt文件(包括readme.txt)。
另外,还可以在配置项中通过core.excludesfile来指定ignore文件。
$ git config core.excludesfile
'_myignore'
git配置
git配置文件根据作用域的不同分为三种:
- 系统配置文件(git安装目录/gitconfig)
- 用户配置文件(用户主目录/.gitconfig)
- 项目配置文件(.git/config)
git配置项都通过git config命令写入,传入不同参数写入不同的配置文件
$ git config --system/--global/
- git config –system 写入系统配置
- git config –global 写入用户配置
- git config 写入项目配置
具体的配置项设置参考帮助文档,$ git config –help
git中的对象
git对象
git中包含4类对象:
- commit 提交对象
- tree 目录
- blob 文件
- tag 标记
git提交便产生一个commit对象,commit对象中包含一个tree对象,tree对象中又会包含其他的tree对象或是blob对
象,blob对象是最小的组成单元,即独立的文件。每个对象都对应一个唯一的SHA-1值,只有当文件或目录有修改时这个值才会重新计算发生改变。
- $ git log 可以查看所有commit对象
- $ git ls-tree <commit> 查看commit对象中的tree对象
- $ git show <blob> 查看blob的具体内容
git原理
究竟git是如何工作的?打开.git目录便可一目了然。
- HEAD 指向当前分支
- config 项目配置文件
- description 供GitWeb程序使用
- hooks/ 客户端与服务端钩子脚本
- info/ 忽略模式
- index 暂存区域信息
- objects/ 所有数据内容
- refs/ 指向所有commit的指针
HEAD文件中是形如以下代码的内容:
ref: refs/heads/dev
它指向refs/heads/dev,而dev文件中代码指向当前分支最近的commit对象
objects目录中保存有所有git对象,这些对象取sha-1值的前两个字母为一个目录,剩下的38个字符作为文件名保存,在上一节“git中
对象”中能查看到的所有git对象都保存在这个目录中,可以使用git cat-file <sha-1>来获取对象内容。
$ git cat-file -p 63a46849
不妨多使用cat-file命名多看看各种对象的内容,有助于理解git对象的结构。
refs目录中保存了git中使用的所有引用或指针,因为不可能任何时候都是用sha-1值来指代对象,git对象也可以有“缩略名”。通常refs目录会包含以下目录:
- heads 保存所有分支的HEAD指针
- remotes 保存远程仓库信息
- tags 保存所有tag指针
逐一地查看这些文件内容,你就什么都明白了。使用 git update-ref 命令可以直接新建一个引用。
$ git update-ref refs/heads/test-branch c56dce
$ git update-ref refs/tags/test-tag c56dce
执行上述命令,这样你的git版本库中就多了一个test-branch分支和一个名为test-tag的tag。
其他的比如git还有些底层的命令,我在文中所列举的,包括之前基础篇的都是一些高级命令。可以使用这些底层命名直接对git库进行一些操作,有关git底层命名的详细内容,可以到网上去找找。