git特点
直接记录快照,而并非差异比较
近乎所有操作都在本地执行
时刻保持数据完整性
多数操作仅添加数据
Git安装
Linux(Ubuntu)
Sudo apt-get install git
Windows
通过msysGit()
或者到https://git-scm.com/download/选择正确版本下载
Mac
安装命令行工具(如已安装Xcode,命令行工具会在首次启动Xcode时提示安装)
Homebrew
Macports
文件的三种状态
已修改(modified)
已暂存(staged)
已提交(commited)
git当中三个区域:工作区,暂存区,版本库
git管理文件的生命周期
Git常用命令
创建版本库
直接使用git init命令
直接clone一个仓库:
$: git clone git@search.ued.taobao.net:projects/search.git
另外一种clone方式:
# 创建目录初始化本地仓库
$: mkdir search && cd search
$: git init
在git clone 的时候,所有本地分之默认与远程主机的同名分之,建立追踪关系,也就是,本地的master分之自动“追踪”origin/master分支。git也可以手动建立追踪, git branch --set-upstream master origin/next --->指定master分之追踪到origin/next。
如果当前分支只有一个追踪分支,连远程主机名都可以省略。$ git pull 表示当前分之自动与唯一一个追踪分之进行合并。
分支操作
查看分支:git branch
创建分支:git branch name
切换分支:git checkout name
创建+切换分支:git checkout -b name
合并某分支到当前分支:git merge name
删除分支:git branch -d name
合并dev分支: git merge --no-ff -m "merge with no-ff" dev
上面我们使用的合并分支是fast forward(快进式合并),这种快速合并的模式,但是有个地方不好的就是不能显示历史信息,在以后开发中我不知道有哪些分支曾经合并过,所以最好使用 no-ff:no fast forward的合并方式,这种方式在合并的同时会生成一个新的commit,这样,从分支历史上就可以看出分支信息。
合并过程中,如果没有冲突的话,merge完成,有冲突的话,git会提示那个文件中有冲突。在解决了所有文件里的所有冲突后,运行 git add 将把它们标记为已解决(resolved)。因为一旦暂存,就表示冲突已经解决。如果你想用一个有图形界面的工具来解决这些问题,不妨运行 git mergetool,它会调用一个可视化的合并工具并引导你解决所有冲突。
Git merge --about 暂时不处理冲突,会清理暂存区
如果你不想把历史汇聚起来,但是想要一个具体分支中的全部commit,使用
Git merge --squash 目标分支名称 这会执行一次提交
删除文件和移动文件
git rm 文件名
删除单独的某个文件, 同时工作区也不需要这个文件了。
git rm --cached file.txt
如果想删除一个文件,不想从文件系统中真正的删除它。告诉git不再跟踪这个文件, 只是不希望这个文件被版本控制.
在git中,重命名和移动文件是同一个事情
Git mv file1.txt file/file2.txt 将文件移动file文件下并命名为file2
当手工移动的时候,git会认为当前目录删除文件,另一个目录untracked了一个文件,使用命令git add -A 就可以合并这两次操作,并tracked文件。
Git commit -a/--all -m “comment”
git add -u 目录名,会从当前目录递归到最深处,寻找它能够添加的所有文件,或者说所有能够被添加的文件(暂存区)
git add -A/--all,使用-A参数会将添加所有改动的已跟踪文件和未跟踪文件。
移动文件,并tracked后,然后commit 会给我们一些数字,这个数字是相似度,表示文件在移动钱湖内容的相似度。Git默认提供一个50%的相似度阈值。如果文件在移动前后,50%相似,它会在移动的过程中追踪它,认为它是一个移动而不仅仅是一个删除和添加。我们可以改变这个阈值。
阈值(100%)
从其他分支提取文件:git checkout [branch] filename
远程仓库操作
# 添加远程仓库路径
$: git remote add github https://github.com/charmingfst/test.git
#如果发现url写错了,那么使用下面的命令修改
Git remote set-url github https://github.com/charmingfst/test.git
上传本地当前分支代码到master分支
$: git push github master
git push origin master (等价于“git push origin master:master”)
git push origin master:master (在local repository中找到名字为master的branch,使用它去更新remote repository下名字为master的branch,如果remote repository下不存在名字是master的branch,那么新建一个)
$git push origin HEAD:refs/for/mybranch (HEAD指向当前工作的branch,master不一定指向当前工作的branch,所以我觉得用HEAD还比master好些)
$git push origin :mybranch (再origin repository里面查找mybranch,删除它。用一个空的去更新它,就相当于删除了)
# 实际上,pull 就是 fetch + merge
$: git pull github --all --tags
git pull -rebase https://github.com/charmingfst/test.git //rebase绕过合并时的冲突
显示所有的远程仓库
$: git remote -v
origin git@search.ued.taobao.net:projects/search.git (fetch)
origin git@search.ued.taobao.net:projects/search.git (push)
github git@github.com:yyfrankyy/search.git (fetch)
github git@github.com:yyfrankyy/search.git (push)
重命名远程仓库
$: git remote rename github gh
$: git remote
origin
gh
删除远程仓库
$: git remote rm github
$: git remote
Origin
从远程仓库抓取数据,更新本地仓库:
$: git fetch origin
查看远程仓库信息,可用于跟踪别人的push:
$: git remote show origin
查看日志
Git log [filename] --oneline查看日志,每次提交信息在一行显示。
Git log sha1值 查看某个具体提交的信息
Git log -p 可以查看版本之间的代码差异。
Git log -n n用数字替代,可以查看最近n条日志记录。
Git log --stat 显示被修改文件的修改统计信息,添加或删除了多少行。
$ git log --since="5 hours" 表示显示5小时内的历史记录。
$ git log --before="5 hours" -1 表示显示5小时前的最后一条记录。
Git支持输出两个版本之间的日志记录。
$ git log 18f822e...0bb3dfb 表示输出在18f822e之后(不包括自己)到0bb3dfb之间(包括自己)的历史记录。
在表示版本的过程中可以使用HEAD表示当前的版本,如:
$ git log 18f822e...HEAD
也可以不输入HEAD,因为GIt假定"..."后面省略的值为HEAD,如:
$ git log 18f822e...
查明该向谁问责
可以使用命令git blame,查看特定代码块的历史信息。该命令的输出结果是代码块中的每行代码前附加前缀信息、其中包括提交名称、提交人和提交时间。
$ git blame file.txt
$ git blame -L 12,13 hello.html 将显示第12、13行代码的信息。
查看差异
显示工作目录树、暂存区及版本库之间的差异:
git diff 工作区修改前后的区别,也就是修改之后还没有暂存起来的变化内容(1)当暂存区中没有文件时,git diff 比较的是,工作区中的文件与上次提交到版本库中的文件(相当于git diff HEAD)。
(2)当暂存区中有文件时,git diff 则比较的是,当前工作区中的文件与暂存区中的文件。
git diff –staged/cached 比较暂存区与版本库之间的差异(git add之后), 查看已暂存的将要添加到下次提交里的内容
git diff HEAD 比较的是工作区中的文件与版本库中文件的差异
git diff id1 id2,显示两次提交之间的差异。
git diff HEAD origin/master 比较当前分支和远程master分支的差异
Gitk查看提交的历史记录
Git reset
有三种模式(mixed(默认),soft,hard)
git reset --hard <commit>,替换引用的指向,替换暂存区,替换工作区
git reset --soft <commit>,只更改引用的指向,撤销相应的更新,把这些更新的内容放到Stage中。
Git reset --soft HEAD^(HEAD^表示当前节点的父节点)
当一些该动太过于分散,把他们弄到一起,比如5条commit,通过使用
Git reset --soft HEAD~5这个命令,把这5条commit当做一次提交。这对于重塑历史非常有用。
git reset –hard
彻底回退到某个版本, 本地的源码也会变为上一个版本的内容
git reset –mixed
此为默认方式,不带任何参数的git reset,就是这种方式,它回退到某个版本,只保留源码,回退commit和stage信息
git reset –soft
回退到某个版本, 只回退了commit的信息,不会恢复stage(如果还要提交,直接commit即可)
git reset HEAD用HEAD 重置暂存区,移除暂存区的变化。
Reset与checkout的不同
Reset经常操作的是整个仓库的历史,checkout作用在一个目录或者文件级别上。
撤销文件修改
1、git reset HEAD filename,将文件filename的改动撤出暂存区,暂存区其他文件不变,会把暂存区的修改回退到工作区,这时可以使用下面的命令继续清楚修改。例如命令:git reset HEAD readme.txt。
2、git checkout -- filename ,改动撤出工作区,命令gitcheckout -- readme.txt(--后有空格)意思就是,把readme.txt文件在工作区的修改全部撤销。
撤销操作版本回朔
1、Git checkout sha1值(不用写全)
此时HEAD处于游离态,不能进行push操作,可以commit操作。提交是无法可见保存的,一旦切到别的分支,游离状态以后的提交就不可追溯了。
2、Git reset --hard <commit>
避免暂存或提交文件
创建.gitignore文件,文件每行内容应与你需要的文件匹配
如 *.log(忽略所有log文件) temp/(忽略temp目录)
修改.gitignore文件后 运行Git add .gitignore,接下来提交的时候匹配的文件就会被忽略。
查看哪些文件被忽略了
Git ls-files --others --ignored --exclude-standard
显示出来的就是被忽略的文件
Reflog命令
Reflog命令会追踪所有的commit,这提供了一个30天的缓存时间,在这期间,你可以从任何错误中恢复,包括git reset命令带来的不好之处
通过git reset --hard hash串,目前的分支被强制切换到那个历史点。
Rebase命令
Rebase命令可以把已存在的提交,放到重新开始的一个分支上。
Rebase命令会修改所有提交在分支中的呈现,它保存你所有的工作。Rebase命令能够让你优化仓库历史的清晰度。
Git rebase master 将当前所在分支的提交放到master分支上。意味着,把所有仅在你分支的所有变更仿佛发生在主分支的当前工作之后
如果需要快速发表特色分支,那么使用merge合并
如果需要清晰的历史,那么使用rebase