赞
踩
http://blog.csdn.net/pipisorry/article/details/50669350
Git有很多命令行参数,使用起来非常方便。可以运行 man git log ,来看一下这些参数的作用。
本博客主要内容git大文件处理、文件比较、git blame用法、git log与git reflog[Git版本控制:Git查阅、撤销文件修改和撤销文件追踪]、文件改动相关、cherry-pick命令、git clean
git commit后,git push前查看要push的文件中是否有大文件
git diff origin/master --name-only | find -size +100M
方法1:预防,大于50M的不添加到git管理中
alias ga='find . -size +100M ! -path *git* | cut -c 3- >> .gitignore; git add .'
或者alias ga='git add . ; find . -size +50M ! -path *git* | xargs git reset HEAD'
Note: 还有一种就是alias ga='find . -size -50M ! -path *git* | xargs git add',不过这条命令如果目录下有subgit项目就会出错error。
方法2:使用lfs强行push上去
这个好像也不行,还是会push出错,并没有用!!!
安装Git LFS lets you store files up to 2 GB in size.
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt install git-lfs
find . -size +50M ! -path *git* | xargs git lfs track
git add .
git commit -m "update"
git push -u origin master
git lfs track设置了文件后,会提示如./song.rar already supported或者
Tracking ./JIM/train.dat
Tracking ./JIM/test_candidate.dat
会新建一个文件.gitattributes,里面内容就是大文件文件名。
quick install[Bash Scripts]
[Install v1.4.1 via PackageCloud (Linux)]
git show some-branch:some-file.js
用这个命令可以很方便地查看其他分支上的文件而无需切换到那个分支。
当然你也可以通过 git show some-branch-name:some-file-name.js 命令在终端中显示指定的文件.
你还可以将输出重定向到一个临时文件,这样你就可以再指定的编辑器中,以并排视图来查看它了。
git show some-branch-name:some-file-name.js > deleteme.js
查看另一个分支上文件与当前分支上文件的差异:
git diff some-branch some-filename.js
比较当前文件和暂存区文件差异,比较两次 commit 之间的差异,比较两个分支之间的差异,比较暂存区和版本库之间的差异等。
对比中+代表后面增加的,-代表后面减少的。
1 git比较暂存区和HEAD的区别
git diff --cached
equals to
git diff --cached HEAD
2 查看push前与远程/当前和fetch后的区别
git diff origin/dev --name-status | grep '.exe'
git diff fetch_head fetch_head^ #git fetch后查看远程的前两次区别,后面加文件名就是只对比指定文件
git diff head fetch_head #git fetch后查看远程和本地区别
git diff fetch_head --name-status #git fetch后查看远程和本地变化的文件名
git diff fetch_head local_filename #git fetch后查看fetch和本地的某个文件区别
git diff origin/master --name-only | xargs grep -size +100M 查看要push的文件中是否有大文件
3 git commit后,查看某个文件的修改:git diff filename
4 对比不同版本:git diff c0f28a2ec490236caa13dec0e8ea826583b49b7a 2e476412c34a63b213b735e5a6d90cd05b014c33
对比当前已提交版本和上一个已提交版本的不同:
git diff HEAD HEAD^1 > 1.txt
加上路径限定符,来只比较某一个文件或目录。(这条命令会显示你当前工作目录下的lib目录与上次提交之间的差别(更准确的说是在当前分支)):
对比当前已提交版本和上第k个已提交版本的不同:
git diff head head~k
git diff HEAD -- ./lib
5 如果不是查看每个文件的详细差别,而是统计一下有哪些文件被改动,有多少行被改动,就可以使用‘--stat' 参数:git diff --stat
1 项目中任意两个分支间的差异
git diff master..test
2 找出‘master’,‘test’的共有 父分支和'test'分支之间的差异
git diff master...test
3 比较项目中任意两个分支间某个文件的差异(文件上的修改不会反映)
git diff master..test ner/NerRuleModel.java
4 显示你当前工作目录与另外一个叫'test'分支的差别(当前工作目录上文件的修改会反映)
git diff test
使用git diff / git difftool比较硬盘上任意两个文件的差异
$git difftool /home/pika/Desktop/jquery-mouse-star-animation/index2.html /home/pika/Desktop/jquery-mouse-star-animation/index.html
或者$git diff /home/pika/Desktop/jquery-mouse-star-animation/index2.html /home/pika/Desktop/jquery-mouse-star-animation/index.html
--- a/home/pika/Desktop/jquery-mouse-star-animation/index2.html
+++ b/home/pika/Desktop/jquery-mouse-star-animation/index.html
@@ -11,8 +11,10 @@
</style>
</head>
<body>
-
-<script type="text/javascript" src="js/mymouse.js" id="mymouse"></script>
-
+<div style="text-align:center;clear:both">
+<script src="/gg_bd_ad_720x90.js" type="text/javascript"></script>
+<script src="/follow.js" type="text/javascript"></script>
+</div>
+ <iframe frameborder="0" scrolling="no" src="index2.html" width="100%" height="500px"></iframe>
</body>
</html>
\ No newline at end of file
上面输出中的---表示index.html中没有的行,+++表示index.html中多出的行(相对于index2)。
差异工具是Meld,在使用Linux的时候可以使用它。
假设你已经选好了比较工具,并且git能够将它作为一个合并和差异工具使用。接下来需要运行一下下面的命令,注意用你选择的差异工具的名字代替Meld:
git config --global diff.tool.meld
git config --global merge.tool meld
之后你就可以运行git difftool some-file.js 来查看文件的差异了。
但是,有些比较工具(例如meld)支持全路径比较。如果你不喜欢meld,也可以使用其他的比较工具,git difftool 支持以下的比较工具:
kdiff3, kompare, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, diffuse, opendiff, p4merge and araxis
如果你调用 git difftool 时加 -d 标志,将会对整个文件夹进行比较。有时会非常有用。
git difftool -d
Meld:一个可视化的文件及目录比较工具,具有的基本功能包括:
能同时完成两个或三个文件的比较,并以图形化的方式给出各个文件的不同处;
能同时完成两个或三个目录的比较,突出显示不相同的文件、删减过的文件;
文件的合并;
文件编辑;
直接制作补丁;
可以比较本地文件与 CVS 中的文件;
安装
meld for max$ brew install meld
meld for linux$ sudo apt-get install meld
meld for windows 下载(镜像)[meld-installer download | SourceForge.net],windows下如果不能正常显示,需要将语言设置为英语[控制面板\时钟、语言和区域-更改显示语言-格式-英语]。[Instll meld in windows]
[meld 官网:Meld]
$meld /home/pika/Desktop/jquery-mouse-star-animation/index2.html /home/pika/Desktop/jquery-mouse-star-animation/index.html &
{让 git diff 使用 meld 的方法:默认的git diff命令比较难看,meld 是最好用的文件比较工具。}
先按上面安装meld
- $mkdir ~/bin/
- $vi ~/bin/git-meld.sh
- #!/bin/bash
- meld $2 $5
- $sudo chmod +x ~/bin/git-meld.sh
- $ git config --global diff.external ~/bin/git-meld.sh
配置成功以后,在某个git管理的文件夹下,修改文件a后,再用git diff a的时候就可以直接用meld察看了。(注意这个比较只能是git管理下的文件才会调用图形界面,否则比较系统中任意两个文件时不会调用meld,所以直接用meld比较更好)
Note: 做shell的原因是GIT会送7个参数给Meld,但是Meld只需要两个参数,两个需要比较的文件名。所以不能直接用Meld。
git difftool 和 git mergetool是专门提供给我们以用自己的工具进行diff和merge的命令。只要配置一下就可以使用了:
git config --global diff.tool meld #配置默认的difftool
git config --global merge.tool meld #配置默认的mergetool
然后输入命令 git difftool HEAD HEAD^1 看看?
使用meld直接比较目录
虽然使用git difftool已经基本满足了我的需要,但还有个小问题:如果我要比较两次提交之间的差异时,difftool只能一个文件一个文件的比较,每次都要提 示你是否打开这个文件,然后打开meld进行比较,当你关闭meld后,才会提示下一个差异文件。这样非常浪费效率。能不能直接利用meld的目录比较能 力呢?
搜了一下,果然有人把脚本写好了: https://github.com/thenigan/git-diffall
也可以到这里下载: http://files.cnblogs.com/pengdonglin137/git-diffall-master.zip
下下来以后,进行如下配置:
git config --global diff.tool meld
git config --global alias.diffall /PATH/TO/YOUR/git-diffall
现在试试 git diffall HEAD HEAD^1 ?
多谢lxd提出遇到的问题与我分享,上述配置会遇到错误 “Expansion of alias ‘diffall’ failed; ‘/xxxx/git-diffall/git-diffall’ is not a git command”,最方便的解决方法就是创建一个软链接在你的PATH路径之一里,比如:
ln -s /PATH/TO/YOUR/git-diffall ~/bin/git-diffall
然后配置
git config --global diff.tool meld #这一行必须配置,否则diffall不知道该使用哪个diff程序
git config –global alias.diffall git-diffall
[git-diff - Show changes between commits, commit and working tree, etc]
出了问题后去责怪别人,是人类的天性。如果你的成品服务器出了问题,你可以非常轻松的把坏人揪出来——只需要使用git blame命令。
运行'git blame [filename]', 你就会得到整个文件的每一行的详细修改信息:包括SHA串、作者、最后一次改动后进行的提交(commit)以及该次提交的时间戳。
Note :Git采用SHA1做为hash签名算法, 在本书中,作者为了表达方便,常常使用SHA来代指SHA1. 如果没有特别说明, 本书中的SHA就是SHA1的代称
git blame test.py
如果文件被修改了(reverted),或是编译(build)失败了; 这个命令就可以大展身手了.
你也可以用"-L"参数在命令(blame)中指定开始和结束行:
$>git blame -L 160,+10 test.py
[Git - git-blame Documentation]
git bisect 使用分治算法查找出错版本号。
假设休假一周回来,你看了一下最新代码,发现走之前完全正常的代码现在出问题了。
你查看了一下休假之前最后一次提交的代码,功能尚且正常。不幸的是,你离开的这段时间,已经有上百次提交记录,你无法找到那一次提交导致了这个问题。
pulling-out-hair
这时你或许想找到破坏功能的bug,然后对该文件使用git blame 命令,找出并指责破坏者。
如果bug很难定位,那么或许你可以去看一下提交历史,试一下看能不能找到出问题的版本。
另一种快捷的方式则是使用git bisect,可以快速找到出问题的版本。
那么git bitsect是如何做的呢?
指定了已知的正常版本和问题版本之后,git bisectit bisect会把指定范围内的提交信息从中间一分为二,并会根据最中间的提交信息创建一个新的分支, 你可以检查这个版本是否有问题。
假设这个中间版本依然可以正常运行。你可以通过git bisect good命令告诉git。然后,你就只有剩下的一半的版本需要测试。
Git会继续分割剩下的版本,将中间版本再次到处让你测试。
Git bisect会继续用相似的方式缩小版本查找范围,直到第一个出问题的版本被找到。
因为你每次将版本分为两半,所以可以用log(n)次查找到问题版本(时间复杂度为“big O”,非常快)。
运行整个git bisect的过程中你会用到的所有命令如下:
git bisect start ——通知git你开始二分查找。
git bisect good {{some-commit-hash}} ——反馈给git 这个版本是没有问题的(例如:你休假之前的最后一个版本)。
git bisect bad {{some-commit-hash}} ——告诉git 已知的有问题的版本(例如master分支中的HEAD)。git bisect bad HEAD (HEAD 代表最新版本)。
这时git 会签出中间版本,并告诉你去测试这个版本。
git bisect bad ——通知git当前版本是问题版本。
git bisect good ——通知git当前签出的版本没有问题。
当找到第一个问题版本后,git会告诉你。这时, git bisect 结束了。
git bisect reset——返回到 git bisect进程的初始状态(例如,master分支的HEAD版本)。
git bisect log ——显示最后一次完全成功的 git bisect日志。
你也可以给git bisect提供一个脚本,自动执行这一过程。详细内容请点击: Git - git-bisect Documentation
通常来讲,创建一个基于特性的提交是一个良好的做法,就是说,每次提交都必须代表一个新特性的产生或者是一个bug的修复。考虑一下,如果你修复了两个bug,或是添加了多个新特性但是却没有提交这些变化会怎样呢?在这种情况下,你可以把这些变化放在一次提交中。但是还有一个更好的方法:把文件分别暂存(Stage)然后分别提交。
比如说,你对一个文件进行了多次修改并且想把他们分别提交。这种情况下,你可以在添加命令(add)中加上-p选项
git add -p [file_name]
让我们演示一下。我在file_name文件中添加了3行文字,而且我只想提交第一行和第三行。我们先看一下git diff显示的结果。
然后,我们看一下,在添加命令(add)中加上-p选项后会发生什么。
看上去,Git假定所有的改变都是针对同一件事情的,因此它把这些都放在了一个块里。你有如下几个选项:
输入y来缓存该块
输入n不缓存该块
输入e来人工编辑该块
输入d来退出或进入下一个文件
输入s来分割这个块
对我们而言,我们肯定希望把它分成几个部分,有选择的添加一部分而忽略其他的。
正如你所看到的,我们添加了第一行和第三行而忽略了第二行。你可以在之后查看仓库状态并进行提交。
当你提交你的代码进行审核并创建一个pull request时(在开源项目中常常发生这样的情况),你经常会在代码被采纳前,要求修改一些代码。你进行了一些修改,而在下一次审核中,又会被要求进行另外的修改。你不知道还有多少次修改等着你,在你知道以前,你进行了多次额外的提交。理想的状态是,你可以使用rebase命令,把他们都合并成一次提交。
git rebase -i HEAD~[number_of_commits]
如果你希望合并最后两次提交,您需要以下命令
git rebase -i HEAD~2
使用该命令,你会进入一个交互式的界面,显示了最后两次提交,并且询问你要压缩哪些。理想状态是你pick最近的一次提交并把它和之前的提交squash。
接下来你会被要求为合并后的这次提交填写描述信息。这一个过程实际上重写了你的提交历史。
尽管reflog是一种查看丢失提交的方法,但是它在大型仓库中行不通。这时就该fsck
(file system check)出场了。
git fsck --lost-found
这里你可以看到丢失的提交,你可以使用git show [commit_hash]来查看这些提交所包含的改动或者是使用git merge [commit_hash]来恢复它。
git fsck比reglog有一个优势。比如你删除了一个远端分支并且克隆了仓库,使用fsck命令你可以搜索并恢复该远端分支。
示例:git pull --rebase
之前我们说过在远程分支上工作会有大量的合并提交。使用 git rebase 可以避免这些提交。
总的来说我认为变更基线是高级特征,最好是留到另一篇文章中详细介绍。
甚至在git book中也有这样的论述:
但是,令人狂喜的变更基线并不是任何情况下都适用,一言以蔽之:
若是工作区中存在尚未提交到仓库的变更,请不要使用变更基线。
如果遵照这条指南,不会有什么问题。不然,你可能会招致厌恶与谩骂。
https://git-scm.com/book/en/v2/Git-Branching-Rebasing#The-Perils-of-Rebasing
也就是说,变更基线本身并不可怕,关键在于使用方式。
或许,最好的方法是使用交互式变更基线,调用命令为 git rebase -i {{某个提交序列号}}。运行这条命令,会打开一个带有自解释指令的编辑器。由于变更基线不在本文的叙述范围之内,我们就此而止,不再深究。
举个例子,假设你正在master分支的一个本地版本上工作,你已经向仓库提交了一小部分变更。与此同时,也有人向master分支提交了他一周的工作成果。当你尝试推送本地变更时,git提示你需要先运行一下 git pull , 来解决冲突。作为一个称职的工程师,你运行了一下 git pull ,并且git自动生成了如下的提交信息。
Merge remote-tracking branch ‘origin/master’
尽管这不是什么大问题,也完全安全,但是不太有利于历史记录的聚合。
这种情况下,git pull --rebase 是一个不错的选择。
这个命令会迫使git将远程分支上的变更同步到本地,然后将尚未推送的提交重新应用到这个最新版本,就好象它们刚刚发生一样。这样就可以避免合并以及随之而来的丑陋的合并信息了。
假设提交之后,你意识到自己犯了一个拼写错误。你可以重新提交一次,并附上描述你的错误的提交信息。但是,还有一个更好的方法:
如果提交尚未推送到远程分支,那么按照下面步骤简单操作一下就可以了:
修复你的拼写错误
将修正过的文件暂存,通过git add some-fixed-file.js
运行 git commit –amend 命令,将会把最近一次的变更追加到你最新的提交。同时也会给你一个编辑提交信息的机会。
准备好之后,将干净的分支推送到远程分支。
图
如果你工作在自己的分支,甚至可以在已经推送之后修正提交,你需要使用 git push -f (-f 代表强制执行),这条指令可以重写历史。但是,不要试图在一个很多人共同工作的分支(正如我们在变更基线那一部分讨论的分支)上这样做。此时,新建一次提交,在提交信息中描述错误,应该是最好的补救措施。
如果打算撤销之前一次或者两次的提交,查看这些提交都做了哪些变更,哪些变更又有可能引发问题,这个命令非常方便。
通常,git revert 会自动将回退的文件提交到仓库,需要你写一个新的提交信息。-n 标志告诉git先别急着提交,因为我只是想看一眼罢了。
它的名字就意味着它的功能!简而言之,cherry-pick是指从不同的分支里选择某次提交并且把它合并到当前的分支来。如果你在并行的开发某两个或多个分支,你可能会注意到有一个bug存在于所有的分支中。如果你在一个分支中解决了它,你可以使用cherry-pick来把这次提交合并进其他的分支而不会搞乱其他的文件或是提交。
让我们想象一个可以使用该命令的场景。我有两个分支,并且我想要把b20fd14: Cleaned junk这次提交使用cherry-pick的方法放入到另一个分支。
我切换到我想要放入该提交的分支,然后运行如下命令:
git cherry-pick [commit_hash]
尽管我们本次使用cherry-pick没什么问题,但是你应该清楚这个命令会带来冲突,请谨慎使用。
删除 一些 没有 git add 的 文件(也就是untracked file)
git clean 参数
-n 显示 将要 删除的 文件 和 目录
-f 删除 文件,-df 删除 文件 和 目录
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。