commit和commit -a的区别, commit -a相当于:

    第一步:自动地add所有改动的代码,使得所有的开发代码都列于index file中
    第二步:自动地删除那些在index file中但不在工作树中的文件
    第三步:执行commit命令来提交

对于有删除文件,可以git commit -a 或 git add -A
注意git add -A 会把我们未通过 git rm 删除的文件全部stage,
git commit -a是删除的文件会自动标记, 但对新建文件就不行

git rm 删除当地文件和index里的文件
git  rm -r 删除文件夹
git rm --cached删除index里的文件

用git show 的时候commit只需要5,6位就可以了

对于add后但没有commit的又想去除的,可以用git reset --filename

当合并失败git会提示那些冲突无法自动合并,有两种解决方法:
手工修改这些文件,合并其中的内容,然后commit。
使用当前分支,或者要合并分支的内容,然后提交
git checkout –ours <conflict file>
git checkout –theirs <conflict file>

git-whatchanged和git diff差不多:
$ git-whatchanged -p init/main.c
7.错误提交了commit怎么办?
a) git-revert
这个本身就会产生一个commit,如果用得多了会让你的log看起来不那么干净。;-)
b) git-reset
用这个要当心,它会把那个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)。
另外,还可以在配置项中通过 c ore.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-object.png
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底层命名的详细内容,可以到网上去找找。