图片转自:http://www.cnblogs.com/1-2-3/archive/2010/07/18/git-commands.html
图片很详细,如果看不清可以保存下来放大查看。
常用命令:
一、新建代码库
# 在当前目录新建一个Git代码库
$ git init
# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]# 下载一个项目和它的整个代码历史
$ git clone [url]
#curl 不输入用户密码 http://用户:密码@gitlab.corp.test.com/test/mywork.git
#或者 git config --global credential.helper store
二、git变量配置
# 显示当前的Git配置
$ git config --list
# 编辑Git配置文件
$ git config -e [--global]# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"
三、增加/删除文件
# 添加指定文件到暂存区
$ git add [file1][file2]...# 添加指定目录到暂存区,包括子目录
$ git add [dir]# 添加当前目录的所有文件到暂存区
$ git add .# 添加每个变化前,都会要求确认
# 对于同一个文件的多处变化,可以实现分次提交
$ git add -p
# 删除工作区文件,并且将这次删除放入暂存区
$ git rm [file1][file2]...# 停止追踪指定文件,但该文件会保留在工作区
$ git rm --cached [file]# 改名文件,并且将这个改名放入暂存区
$ git mv [file-original][file-renamed]
四、代码提交
# 提交暂存区到仓库区
$ git commit -m [message]# 提交暂存区的指定文件到仓库区
$ git commit [file1][file2]...-m [message]# 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a
# 提交时显示所有diff信息
$ git commit -v
# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1][file2]...
五、分支
# 列出所有本地分支
$ git branch
# 列出所有远程分支
$ git branch -r
# 列出所有本地分支和远程分支
$ git branch -a
# 新建一个分支,但依然停留在当前分支
$ git branch [branch-name]# 新建一个分支,并切换到该分支
$ git checkout -b [branch]# 新建一个分支,指向指定commit
$ git branch [branch][commit]# 新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch][remote-branch]# 切换到指定分支,并更新工作区
$ git checkout [branch-name]# 切换到上一个分支
$ git checkout -# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch][remote-branch]# 合并指定分支到当前分支
$ git merge [branch]# 选择一个commit,合并进当前分支
$ git cherry-pick [commit]# 删除分支
$ git branch -d [branch-name]# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
六、标签
# 列出所有tag
$ git tag
# 新建一个tag在当前commit
$ git tag [tag]# 新建一个tag在指定commit
$ git tag [tag][commit]# 删除本地tag
$ git tag -d [tag]# 删除远程tag
$ git push origin :refs/tags/[tagName]# 查看tag信息
$ git show [tag]# 提交指定tag
$ git push [remote][tag]# 提交所有tag
$ git push [remote]--tags
# 新建一个分支,指向某个tag
$ git checkout -b [branch][tag]
七、查看信息
# 显示有变更的文件
$ git status
# 显示当前分支的版本历史
$ git log
# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat
# 搜索提交历史,根据关键词
$ git log -S [keyword]# 显示某个commit之后的所有变动,每个commit占据一行
$ git log [tag] HEAD --pretty=format:%s
# 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature
# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]# 显示指定文件相关的每一次diff
$ git log -p [file]# 显示过去5次提交
$ git log -5--pretty --oneline
# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn
# 显示指定文件是什么人在什么时间修改过
$ git blame [file]# 显示暂存区和工作区的差异
$ git diff
# 显示暂存区和上一个commit的差异
$ git diff --cached [file]# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD
# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"# 显示某次提交的元数据和内容变化
$ git show [commit]# 显示某次提交发生变化的文件
$ git show --name-only [commit]# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]# 显示当前分支的最近几次提交
$ git reflog
八、远程同步
# 下载远程仓库的所有变动
$ git fetch [remote]# 显示所有远程仓库
$ git remote -v
# 显示某个远程仓库的信息
$ git remote show [remote]# 增加一个新的远程仓库,并命名
$ git remote add [shortname][url]# 取回远程仓库的变化,并与本地分支合并
$ git pull [remote][branch]# 上传本地指定分支到远程仓库
$ git push [remote][branch]# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote]--force
# 推送所有分支到远程仓库
$ git push [remote]--all
九、撤销
# 恢复暂存区的指定文件到工作区
$ git checkout [file]# 恢复某个commit的指定文件到暂存区和工作区
$ git checkout [commit][file]# 恢复暂存区的所有文件到工作区
$ git checkout .# 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
$ git reset [file]# 重置暂存区与工作区,与上一次commit保持一致
$ git reset --hard
# 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
$ git reset [commit]# 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
$ git reset --hard [commit]# 重置当前HEAD为指定commit,但保持暂存区和工作区不变
$ git reset --keep [commit]# 新建一个commit,用来撤销指定commit
# 后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [commit]# 暂时将未提交的变化移除,稍后再移入
$ git stash
$ git stash pop
十、其他
# 生成一个可供发布的压缩包
$ git archive
$ git archive --format zip --output /path/to/file.zip master # 将 master 以zip格式打包到指定文件
=========================================================================================================
1) 远程仓库相关命令
检出仓库:$ git clone git://github.com/jquery/jquery.git
查看远程仓库:$ git remote -v
添加远程仓库:$ git remote add [name] [url]
删除远程仓库:$ git remote rm [name]
修改远程仓库:$ git remote set-url --push [name] [newUrl]
拉取远程仓库:$ git pull [remoteName] [localBranchName]
推送远程仓库:$ git push [remoteName] [localBranchName]
*如果想把本地的某个分支test提交到远程仓库,并作为远程仓库的master分支,或者作为另外一个名叫test的分支,如下:
$git push origin test:master // 提交本地test分支作为远程的master分支
$git push origin test:test // 提交本地test分支作为远程的test分支
2)分支(branch)操作相关命令
查看本地分支:$ git branch
查看远程分支:$ git branch -r
创建本地分支:$ git branch [name] ----注意新分支创建后不会自动切换为当前分支
切换分支:$ git checkout [name]
创建新分支并立即切换到新分支:$ git checkout -b [name]
删除分支:$ git branch -d [name] ---- -d选项只能删除已经参与了合并的分支,对于未有合并的分支是无法删除的。如果想强制删除一个分支,可以使用-D选项
合并分支:$ git merge [name] ----将名称为[name]的分支与当前分支合并
创建远程分支(本地分支push到远程):$ git push origin [name]
删除远程分支:$ git push origin :heads/[name] 或 $ gitpush origin :[name]
*创建空的分支:(执行命令之前记得先提交你当前分支的修改,否则会被强制删干净没得后悔)
$git symbolic-ref HEAD refs/heads/[name]
$rm .git/index
$git clean -fdx
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]
合并远程仓库的tag到本地:$ git pull origin --tags
上传本地tag到远程仓库:$ git push origin --tags
创建带注释的tag:$ git tag -a [name] -m 'yourMessage'
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 查看本地所有分支
git status 查看当前状态
git commit 提交
git branch -a 查看所有的分支
git branch -r 查看本地所有分支
git commit -am "init" 提交并且加注释
git remote add origin git@192.168.1.119:ndshow
git push origin master 将文件给推到服务器上
git remote show origin 显示远程库origin里的资源
git push origin master:develop
git push origin master:hb-dev 将本地库与服务器上的库进行关联
git checkout --track origin/dev 切换到远程dev分支
git branch -D master develop 删除本地库develop
git checkout -b dev 建立一个新的本地分支dev
git merge origin/dev 将分支dev与当前分支进行合并
git checkout dev 切换到本地dev分支
git remote show 查看远程库
git add .
git rm 文件名(包括路径) 从git中删除指定文件
git clone git://github.com/schacon/grit.git 从服务器上将代码给拉下来
git config --list 看所有用户
git ls-files 看已经被提交的
git rm [file name] 删除一个文件
git commit -a 提交当前repos的所有的改变
git add [file name] 添加一个文件到git index
git commit -v 当你用-v参数的时候可以看commit的差异
git commit -m "This is the message describing the commit" 添加commit信息
git commit -a -a是代表add,把所有的change加到git index里然后再commit
git commit -a -v 一般提交命令
git log 看你commit的日志
git diff 查看尚未暂存的更新
git rm a.a 移除文件(从暂存区和工作区中删除)
git rm --cached a.a 移除文件(只从暂存区中删除)
git commit -m "remove" 移除文件(从Git中删除)
git rm -f a.a 强行移除修改后文件(从暂存区和工作区中删除)
git diff --cached 或 $ git diff --staged 查看尚未提交的更新
git stash push 将文件给push到一个临时空间中
git stash pop 将文件从临时空间pop下来
---------------------------------------------------------
git remote add origin git@github.com:username/Hello-World.git
git push origin master 将本地项目给提交到服务器中
-----------------------------------------------------------
git pull 本地与服务器端同步
-----------------------------------------------------------------
git push (远程仓库名) (分支名) 将本地分支推送到服务器上去。
git push origin serverfix:awesomebranch
------------------------------------------------------------------
git fetch 相当于是从远程获取最新版本到本地,不会自动merge
git commit -a -m "log_message" (-a是提交所有改动,-m是加入log信息) 本地修改同步至服务器端 :
git branch branch_0.1 master 从主分支master创建branch_0.1分支
git branch -m branch_0.1 branch_1.0 将branch_0.1重命名为branch_1.0
git checkout branch_1.0/master 切换到branch_1.0/master分支
du -hs
-----------------------------------------------------------
mkdir WebApp
cd WebApp
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin git@github.com:daixu/WebApp.git
git push -u origin master
=========================================================================================================
1. 安装后的第一步
在安装好git后,你第一件该做的事是设置你的名字和电子邮箱,因为每次提交都要用到这些信息:
$ git config --global user.name "Some One"
$ git config --global user.email "someone@gmail.com"
2. Git是基于指针的
保存在git里的一切都是文件。当你创建一个提交的时候,会建立一个包含你的提交信息和相关数据(名字,邮件地址,日期/时间,前一个提交,等等)的文件,并把它链接到一个树文件中。这个树文件中包含了对象或其他树的列表。这里的提到的对象(或二进制大对象)是和本次提交相关的实际内容(它也是一个文件,另外,尽管文件名并没有包含在对象里,但是存储在树中)。所有这些文件都使用对象的SHA-1哈希值
作为文件名。
用这种方式,分支和标签就是简单的文件(基本上是这样),包含指向该提交的SHA-1哈希值
。使用这些索引会带来优秀的灵活性和速度,比如创建一个新分支就是简单地用分支名字和所分出的那个提交的SHA-1
索引来创建一个文件。当然,你不需要自己做这些,而只要使用Git命令行工具(或者GUI),但是实际上就是这么简单。
你也许听说过叫HEAD的索引。这只是简单的一个文件,包含了你当前指向的那个提交的SHA-1索引值。如果你正在解决一次合并冲突然后看到了HEAD,这并不是一个特别的分支或分支上的一个必需的特殊位置,只是标明你当前所在位置。
所有的分支指针都保存在.git/refs/heads
里,HEAD在.git/HEAD
里,而标签保存在.git/refs/tags
里 - 自己可以随便进去看看。
3. 两个爸爸(父节点) - 你没看错!
在历史中查看一个合并提交的信息时,你将看到有两个父节点(不同于工作副本上的常规提交的情况)。第一个父节点是你所在的分支,第二个是你合并过来的分支。
4. 合并冲突
目前我相信你碰到过合并冲突并且解决过。通常是编辑一下文件,去掉<<<<,====,>>>>标志,保留需要留下的代码。有时能够看到这两个修改之前的代码会很不错,比如,在这两个现在冲突的分支之前的改动。下面是一种方式:
$ git diff --merge
diff --cc dummy.rb
index 5175dde,0c65895..4a00477
--- a/dummy.rb
+++ b/dummy.rb
@@@ -1,5 -1,5 +1,5 @@@
class MyFoo
def say
- puts "Bonjour"
- puts "Hello world"
++ puts "Annyong Haseyo"
end
end
如果是二进制文件,比较差异就没那么简单了...通常你要做的就是测试这个二进制文件的两个版本来决定保留哪个(或者在二进制文件编辑器里手工复制冲突部分)。从一个特定分支获取文件拷贝(比如说你在合并master
和feature123
两个分支):
$ git checkout master flash/foo.fla # 或者...
$ git checkout feature132 flash/foo.fla
$ # 然后...
$ git add flash/foo.fla
另一种方式是通过git输出文件 - 你可以输出到另外的文件名,然后当你决定了要用哪个后,再将选定的正确文件复制为正常的文件名:
$ git show master:flash/foo.fla > master-foo.fla
$ git show feature132:flash/foo.fla > feature132-foo.fla
$ # 检出master-foo.fla和feature132-foo.fla
$ # 假如说我们决定来自feature132的文件是正确的
$ rm flash/foo.fla
$ mv feature132-foo.fla flash/foo.fla
$ rm master-foo.fla
$ git add flash/foo.fla
更新:感谢Carl在原博客文章上评论里的提醒,你实际上可以用“git checkout —ours flash/foo.fla
”和“git checkout —theirs flash/foo.fla
”来检出特定版本的文件,而不用记住你在合并的分支名字。就我个人来说喜欢更精确一点,但这也是一种方式...
记着在解决完冲突后要将文件加入提交(像我上面做的那样)。
服务器,分支和标签5. 远端服务器
git的一个超强大的功能就是可以有不止一个远端服务器(实际上你一直都在一个本地仓库上工作)。你并不是一定都要有这些服务器的写权限,你可以有多个可以读取的服务器(用来合并他们的工作)然后写入到另外一个仓库。添加一个新的远端服务器很简单:
$ git remote add john git@github.com:johnsomeone/someproject.git
如果你想查看远端服务器的信息可以这样做:
# 显示每个远端服务器的URL
$ git remote -v
# 提供更多详细信息
$ git remote show name
你随时都可以查看本地分支和远端分支的差异:
$ git diff master..john/master
你也可以查看没有在远端分支上的HEAD的改动:
$ git log remote/branch..
# 注意:..后面没有结束的特定引用
6. 标签
在git里有两种类型的标签 - 轻量级标签和带注释标签。记住技巧2里说过git是基于指针的,这两者之间的差异也很简单。轻量级标签只是一个简单的指向一次提交的带名字指针。你随时都可以将它指向另一个提交。带注释标签是一个指向标签对象的带名字指针,带有自己的信息和历史。因为有自己的信息,它可以根据需要用GPG签名。
建立这两种类型的标签都很简单(只有一个命令行开关的差异)
$ git tag to-be-tested
$ git tag -a v1.1.0 # 会提示输入标签的信息
7. 建立分支
在git里建立分支非常简单(而且像闪电一样快,因为它只需要创建一个小于100字节的文件)。用普通方式建立新分支并切换过去:
$ git branch feature132
$ git checkout feature132
当然,如果你确定自己直接切换到新建的分支,可以用一个命令实现:
$ git checkout -b feature132
如果你想重命名一个本地分支也很简单(可以显示发生了什么的较长的方式):
$ git checkout -b twitter-experiment feature132
$ git branch -d feature132
更新:你也可以(像Brian Palmer在原博客文章的评论里提出的)只用“git branch”的-m开关在一个命令里实现(像Mike提出的,如果你只指定了一个分支参数,就会重命名当前分支):
$ git branch -m twitter-experiment
$ git branch -m feature132 twitter-experiment
8. 合并分支
也许在将来的某个时候,你希望将改动合并。有两种方式:
$ git checkout master
$ git merge feature83 # 或者...
$ git rebase feature83
merge
和rebase
之间的差别是merge
会尝试处理改动并建立一个新的混合了两者的提交。rebase
会尝试把你从一个分支最后一次分离后的所有改动,一个个加到该分支的HEAD
上。不过,在已经将分支推到远端服务器后不要再rebase
了 - 这会引起冲突/问题。
如果你不确定在哪些分支上还有独有的工作 - 所以你也不知道哪些分支需要合并而哪些可以删除,git branch
有两个开关可以帮你:
# 显示已经全部合并到当前分支的分支
$ git branch --merged
# 显示没有合并到当前分支的分支
$ git branch --no-merged
9. 远端分支
如果你在本地有一个分支希望推到远端服务器上,你可以用一行命令推送上去:
$ git push origin twitter-experiment:refs/heads/twitter-experiment
# origin是我们服务器的名字,而twitter-experiment是分支名字
更新:感谢Erlend在原博客文章上的评论 - 这个实际上和git push origin twitter-experiment
效果一样,不过使用完整的语法,你可以在两者之间使用不同的分支名(这样本地分支可以是add-ssl-support
而远端是issue-1723
)。
如果你想在远端服务器上删除一个分支(注意分支名前面的冒号):
$ git push origin :twitter-experiment
如果你想查看所有远端分支的状态可以这样做:
$ git remote show origin
这个命令可能会列出服务器上一些以前有过但现在已经不在了的分支。如果碰到这种情况你可以用下面的命令从你本地分支里清理掉:
$ git remote prune
最后,如果你想在本地跟踪一个远端分支,普通的方式是:
$ git branch --track myfeature origin/myfeature
$ git checkout myfeature
不过,新版的git在使用-b标记检出分支时会自动设定跟踪:
$ git checkout -b myfeature origin/myfeature
在储藏点,索引和文件系统中保存内容
10. 储藏
在git里你可以把当前工作状态放进一个储藏堆栈中,然后可以再取出来。最简单的情形是下面这样:
$ git stash
# 做点其他事情...
$ git stash pop
许多人建议使用git stash apply
来代替pop
,不过如果这样做的话最后会遗留一个很长的储藏列表。而“pop”
会在全部加载后自动从堆栈中移除。如果使用过git stash apply
,你也可以使用下面的命令从堆栈上移除最后一项:
$ git stash drop
git会基于当前的提交信息自动创建评论。如果你更希望有自定义信息的话(因为它可能和前一个提交没有任何联系):
$ git stash save "My stash message"
如果你希望从列表中取出一个特定的储藏点(不一定非得是最后一个)可以先列出它们然后用下面的方式取出:
$ git stash list
stash@{0}: On master: Changed to German
stash@{1}: On master: Language is now Italian
$ git stash apply stash@{1}
11. 交互式添加
在subversion的世界里你只能修改文件然后提交所有改动。而在git里你有强大得多的方式来提交部分文件或者甚至是部分补丁。提交部分文件或文件中的部分改动你需要进入交互式模式:
$ git add -i
staged unstaged path
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now>
这会让你进入一个基于菜单的交互式提示。你可以使用命令中的数字或高亮的字母(如果你在终端里打开了高亮的话)来进入相应的模式。然后就只是输入你希望操作的文件的数字了(你可以使用这样的格式,1或者1-4或2,4,7)。
如果你想进入补丁模式(交互式模式下按‘p’或‘5’),你也可以直接进入:
$ git add -p
diff --git a/dummy.rb b/dummy.rb
index 4a00477..f856fb0 100644
--- a/dummy.rb
+++ b/dummy.rb
@@ -1,5 +1,5 @@
class MyFoo
def say
- puts "Annyong Haseyo"
+ puts "Guten Tag"
end
end
Stage this hunk [y,n,q,a,d,/,e,?]?
你可以看到下方会有一些选项供选择用来添加该文件的这个改动、该文件的所有改动,等等。使用‘?’命令
可以详细解释这些选项。
12. 从文件系统里保存/取回改动
有些项目(比如Git项目本身)在git文件系统中直接保存额外文件而并没有将它们加入到版本控制中。
让我们从在git中存储一个随机文件开始:
$ echo "Foo" | git hash-object -w --stdin
51fc03a9bb365fae74fd2bf66517b30bf48020cb
这样这个目标文件就已经保存到数据库中了,但是如果你没有设定一个指向它的指针的话它会被当做垃圾回收。最简单的方式是设定一个标签:
$ git tag myfile 51fc03a9bb365fae74fd2bf66517b30bf48020cb
注意这里我们使用了标签myfile
。当我们需要使用这个文件的时候可以这样做:
$ git cat-file blob myfile
这个对于一些工具文件很有用,开发者可能会用到(密码,GPG密钥,等等)但是又不希望每次都检出到硬盘(尤其是在实际工作中)。
日志以及有哪些改动?13. 查看日志
长时间使用 Git 的话,不会没用过‘git log
’来查看最近的提交。不过,有一些技巧来更好地应用。比如,你可以使用下面的命令来查看每次提交的具体改动:
$ git log -p
或者你可以仅仅查看有哪些文件改动:
$ git log --stat
有个很不错的别名你可以试试,会显示简短提交名和一个不错的分支图并在一行里显示提交信息(有点像gitk,但是是在命令行下):
$ git config --global alias.lol "log --pretty=oneline --abbrev-commit --graph --decorate"
$ git lol
* 4d2409a (master) Oops, meant that to be in Korean
* 169b845 Hello world
14. 搜索日志
如果你想找特定提交者可以这样做:
$ git log --author=Andy
更新:感谢Johannes的评论,我已经去掉了之前这里的一些有混淆的地方。
或者你想在提交信息里找一些相关字段:
$ git log --grep="Something in the message"
也有一个更强大的叫做pickaxe
的命令用来查找包含了删除或添加的某个特定内容的提交(比如,该内容第一次出现或被删除)。这可以告诉你什么时候增加了一行(但这一行里的某个字符后面被改动过就不行了):
$ git log -S "TODO: Check for admin status"
假如你改动了一个特定的文件,比如lib/foo.rb
$ git log lib/foo.rb
比如说你有一个feature/132
分支和feature/145
分支,然后你想看看这两个分支上不在master
分支里的提交(注意符号是不在的意思):
$ git log feature/132 feature/145 ^master
你也可以使用ActiveSupport
格式的日期来缩小到某个日期范围:
$ git log --since=2.months.ago --until=1.day.ago
默认情况下会用OR来组合查询,但你可以轻易地改为AND(如果你有超过一条的查询标准)
$ git log --since=2.months.ago --until=1.day.ago --author=andy -S "something" --all-match
15. 查看/修改版本
有很多方式可以用来引用一个版本,看你记得哪个:
$ git show 12a86bc38 # 根据版本
$ git show v1.0.1 # 根据标签
$ git show feature132 # 根据分支名
$ git show 12a86bc38^ # 一次提交的父节点
$ git show 12a86bc38~2 # 一次提交的祖父节点
$ git show feature132@{yesterday} # 时间相关
$ git show feature132@{2.hours.ago} # 时间相关
注意和之前部分有些不同,末尾的的意思是该提交的父节点- 开始位置的的意思是不在这个分支。
16. 选择范围
最简单的方式:
$ git log origin/master..new
# [old]..[new] - 所有你还没有推送的提交
你也可以省略[new]
,将使用当前的HEAD
。
17. 重置改动
如果你还没有提交的话可以用下面的命令轻松地取消改动:
$ git reset HEAD lib/foo.rb
通常会使用‘unstage
’的别名,因为上面的看上去有些不直观。
$ git config --global alias.unstage "reset HEAD"
$ git unstage lib/foo.rb
如果你已经提交了该文件,你可以做两件事 - 如果是最后一次提交你还可以改正:
$ git commit --amend
这会取消最后一次提交,把工作分支回退到提交前标记了所有改动的状态,而且提交信息也都准备好可以修改或直接提交。
如果你已经提交过多次而且希望全部回退,你可以将分支重置到合适的位置。
$ git checkout feature132
$ git reset --hard HEAD~2
如果你实际上希望将分支指向一个完全不同的SHA1
(也许你要将一个分支的HEAD替换到另一个分支,或者之后的某次提交)你可以使用下面的较长的方式:
$ git checkout FOO
$ git reset --hard SHA
实际上有一个快速的方式(不需要先把你的工作分支切换到FOO
再前进到SHA
):
$ git update-ref refs/heads/FOO SHA
18. 提交到了错误的分支
好吧,假如说你已经提交到了master
,但却应该创建一个叫experimental
的主题分支更合适。要移动这些改动,你可以在当前位置创建分支,回退HEAD再检出新分支:
$ git branch experimental # 创建一个指向当前master的位置的指针
$ git reset --hard master~3 # 移动master分支的指针到3个版本之前
$ git checkout experimental
如果你的改动是在分支的分支的分支上会更复杂。那样你需要做的是将分支基础切换到其他地方:
$ git branch newtopic STARTPOINT
$ git rebase oldtopic --onto newtopic
19. 交互式切换基础
这是一个我之前看过展示却没真正理解过的很赞的功能,现在觉得它就很简单了。假如说你提交了3次但是你希望更改顺序或编辑(或者合并):
$ git rebase -i master~3
然后这会启动你的编辑器并带有一些指令。你所要做的就是修改这些指令来选择/插入/编辑(或者删除)提交和保存/退出。然后在编辑完后你可以用git rebase --continue
命令来让每一条指令生效。
如果你有修改,将会切换到你提交时所处的状态,之后你需要使用命令git commit --amend
来编辑。
注意:在rebase的时候千万不要提交 - 只能先添加然后使用参数--continue
,--skip
或--abort
。
20. 清理
如果你提交了一些内容到你的分支(也许你从SVN导入了一些旧仓库),然后你希望把某个文件从历史记录中全部删掉:
$ git filter-branch --tree-filter 'rm -f *.class' HEAD
如果你已经推送到origin了,但之后提交了一些垃圾改动,你也可以在推送前在本地系统里这样做:
$ git filter-branch --tree-filter 'rm -f *.class' origin/master..HEAD
其他技巧
21. 你查看过的前一个引用
如果你知道自己之前查看过一个SHA-1
,但是随后做了一些重置/回退的操作,你可以使用reflog命令
来列出最近查看过的SHA-1
记录:
$ git reflog
$ git log -g # 和上面一样,但是使用'log'格式输出
22. 分支命名
一个可爱的小技巧 - 别忘了分支名并不限于a-z和0-9。名字中可以用/和.将非常方便用来建立伪命名空间或版本,例如:
$ # 生成版本132的改动历史
$ git shortlog release/132 ^release/131
$ # 贴上v1.0.1的标签
$ git tag v1.0.1 release/132
23. 找出谁是凶手
通常找出来谁改动了某个文件里的某行代码会很有用。实现这个功能的最简单命令是:
$ git blame FILE
有时候这些改动来自其他文件(如果你合并了两个文件,或者你移动了某个函数)所以你可以使用下面的命令:
$ # 显示内容来自哪个文件
$ git blame -C FILE
有时候通过点击各个改动然后回到很早很早以前来跟踪改动会很不错。有一个很好的内建GUI命令
来做这个:
$ git gui blame FILE
24. 数据维护
通常git不需要经常维护,它把自己照顾的很好。不过,你可以通过下面的命令查看数据统计:
$ git count-objects -v
如果占用很多空间的话,你可以选择在你的本地仓库做垃圾回收。这不会影响推送或其他人,却会让一些命令运行更快而且减少空间占用:
$ git gc
经常运行完整性检查也很有意义:
$ git fsck --full
你也可以在末尾加上--auto
参数(如果你在服务器上通过crontab经常/每天都运行这个命令的话),然后它只会在必要的时候才执行fsck动作。
在检查的时候,看到“dangling
”或“unreachable
”是正常的,通常这是由回退HEAD或切换基础的结果。而看到“missing
”或“sha1 mismatch
”就不对了...找专业人士帮忙吧!
25. 恢复遗失的分支
如果你使用-D
参数删除了experimental
分支,可以用下面的命令重新建立:
$ git branch experimental SHA1_OF_HASH
如果你最近访问过的话,你通常可以用git reflog
来找到SHA1
哈希值。
另一种方式是使用git fsck —lost-found
。其中一个dangling
的提交就是丢失的HEAD
(它只是已删除分支的HEAD
,而HEAD
被引用为当前的HEAD
所以它并不处于dangling
状态)
作者: IT程序狮
链接:http://www.imooc.com/article/1089
来源:慕课网
=========================================================================================================
http://www.oschina.net/question/565065_86025
http://wjchan.com/blog/2016/04/21/git-command.html
https://www.jqlinux.com/archives/719
http://blog.youkuaiyun.com/dengsilinming/article/details/8000622