Git学习总结

Git学习总结

标签(空格分隔): git 总结

1. 基础 GIT BASICS

1.1 获取Git仓库

  • 在已有目录下初始化仓库
$ cd path #进入目录
$ git init #创建.git目录,含初始化内容

$ git add 文件名 #添加现有文件到暂存区,使用通配符“*”可以将所有文件都添加进去。支持正则表达式匹配
$ git commit -m"提交注解" #把暂存区的文件都提交到本地仓库中去
  • 在空目录下获取远程服务器的仓库
$ git clone URL #获取URL下的仓库,会直接下载到当前目录。如果没有提前配置git账号信息,会要求验证通过才可下载

$ git clone URL project_new_name #下载远程仓库,并且重命名本地的仓库

也可以通过SSH方式获取远程仓库,如【user@server:path/to/repo.git】

1.2 记录更新到本地仓库

  • 查看文件状态
$ git status #文件状态包括“未跟踪”(新建文件就是未跟踪状态)、“暂存”、“新建”、“已编辑更改”。注意看列出的详细解释。

$ git status -s #作用同上。输出会有大概以下的内容:
?? a.txt #“??”表示未跟踪文件
A  b.txt #“A ”已跟踪文件即已添加到暂存区(注意A右边有个空格)
 M c.txt #“ M”已修改但未跟踪(注意M左边有个空格)
M  d.txt #“M ”已修改且已跟踪,被添加到暂存区(注意M右边有个空格)
MM e.txt #已修改且已被跟踪添加到暂存区后,又被修改了,而后面的更改还没有跟踪添加暂存区。如果此时提交commit,则只会提交前一次添加到暂存区的内容,新修改不会被提交。
  • 查看提交历史
$ git log #直接显示所有提交记录,含提交时间和提交者

#其他常用的命令
$ git log -p #除了显示提交时间和提交者外,还显示提交的注解内容
$ git log --stat #查看提交的统计数据
$ git log --pretty=oneline #以一行输出提交的信息(部分提交的校验和、提交注解说明)
$ git log --pretty=format:"%H %cn % ce %s" #格式化输出提交历史内容
$ git log -p -n #显示最近n条提交记录
$ git log --author=Jack #显示Jack这个作者(修改文件)相关的记录
$ git log --committer=Jack #显示Jack这个提交者(提交文件)提交的记录
$ git log --before=“2017-12-30” #显示2017-12-30之前提交的记录,“--before”和“--until”同作用
$ git log --after=“2017-12-30” #显示2017-12-30之后提交的记录,“--after”和“--since”同作用
$ git log --grep=“xxx” #显示提交注解内容里和字符串“xxx”相关的提交记录

其中格式化输出参数含义如下:

%H:提交对象(commit)的完整哈希字串
%h:提交对象的简短哈希字串
%T:树对象(tree)的完整哈希字串
%t:树对象的简短哈希字串
%P:父对象(parent)的完整哈希字串
%p:父对象的简短哈希字串
%an:作者(author)的名字
%ae:作者的电子邮件地址
%ad:作者修订日期(可以用 --date= 选项定制格式)
%ar:作者修订日期,按多久以前的方式显示
%cn:提交者(committer)的名字
%ce:提交者的电子邮件地址
%cd:提交日期
%cr:提交日期,按多久以前的方式显示
%s:提交说明
  • 添加文件到暂存区
$ git add 文件 #可将新建的、已更改的文件添加到暂存区,暂存区的内容可以被提交到本地仓库

文件添加到暂存区以后,文件的状态就又未跟踪untracked变为已暂存staged。暂存区其实也只是一个索引文件index,指向相关被跟踪文件。

  • 忽略特殊文件,不添加到暂存区
$ touch .gitignore #在和.git目录同级地方新建.gitignore文件
$ vi .gitinore #添加忽略的文件类型,如下。
#临时的副本文件
*.[oa]
*~

# Eclipse
.classpath
.project
.settings/

# Intellij
.idea/
*.iml
*.iws

# Mac
.DS_Store

# Maven
log/
target/
out/

# Others
bin/
.myeclipse

“*”任意个字符,“**”中间任意目录,“?”一个字符,“[0-9]”匹配数字0到9,“[abc]”匹配其中一个字符。

  • 比较文件内容变化
$ git diff #不加参数直接执行该命令

git diff比较的是工作目录的文件和暂存区的文件之间的差异,如果同一个文件已经被跟踪添加到了暂存区后又被修改,git diff就会把发生变化的具体内容详细列出来,很好用。

  • 提交更新
    在git add命令后把文件添加到了暂存区,接下来就是要把暂存区的文件提交到本地仓库中去。
$ git commit -m"本次提交注解说明"

每一次提交都是对本地项目的一个快照,以后可以回到任何一个快照节点,或者对不同快照进行对比。

为了方便,可以跳过将文件添加到暂存区这一步,直接提交文件到本地仓库。但是前提条件是这些文件都不是新建的,且之前也已经被跟踪过,即文件被git add过放到暂存区了,现在做了更改,此时在提交时添加“-a”参数即可让系统自动添加到暂存区然后一并提交。

$ git commit -a -m“本次提交注解说明”

1.3 打标签 tags

可以给历史上任何一次提交打个标签,说明该次提交的重要性,比如版本发布时的提交可以打标签“v1.0”、“v2.3”等。

$ git tag #列出所有的标签
$ git tag -l 'v2.3.*' #正则表达式匹配过滤,仅显示前缀为“v2.3.”的标签,根据自己需要可以更改匹配内容
$ git show 标签名称 #列出和标签相关的提交时的完整信息

$ git tag -a 标签名称 -m"关于标签的描述说明"  #创建一个附注标签,含提交人和时间等完整信息
$ git tag 标签名称 #创建一个轻量标签,和附注标签相比,其不含任何信息,只是标记该次提交,即该次提交的引用别名

如果提交已经完成,想要给过去忘了的地方打上标签,可以先查看得到想要打标签的校验和或部分校验和,然后也可以完成打标签操作,如下:

$ git tag -a 标签名 校验和 #在可以区分其他提交的时候检验和也可以只是一部分,如可以使用完整的校验和“4682c3261057305bdd616e23b64b0857d832627b”,也可以使用前面一部分校验和“4682c32” (需要确保唯一)

使用【git push】命令时默认不会把标签推送到远程仓库,需要显式推送才行。

$ git push [remote_name] [branch_name] 标签名称 #推送一个标签到远程仓库
$ git push [remote_name] [branch_name] --tags #推送本地所有的标签到远程仓库

将本地的标签推送到远程仓库之后,其他人拉取的时候就可以一同把你推送的标签获取下来了。

1.4文件操作

  • 删除
    情况1:想要把文件永久删除,即同时删除磁盘上的和git本地仓库内的文件。
$ rm -f 文件名  # -f表示强制执行。先强制删除磁盘上的文件
$ git -f rm 文件名  # -f表示强制执行。然后强制删除暂存区内的文件,即从跟踪文件列表中删除
$ git commit -m"提交删除文件xxx" #提交暂存区的变化,即把已删除文件删除,不再纳入版本管理中

情况2:想要把文件从git本地仓库删除,但是保留磁盘上的文件。如不小心把很大的log文件添加到git仓库,需要从git仓库中删除并且不要被跟踪,但是磁盘上的日志文件需要保留下来。

$ git rm --cache 文件名  # --cache意思就是删除暂存区内文件
  • 重命名文件
$ git mv file_old_name file_new_name #重命名文件

上面重命名文件的命令,相当于下面三条命令:

$ mv file_old_name file_new_name # 重命名磁盘上工作目录的文件
$ git rm file_old_name # 删除暂存区的文件,即把文件从被跟踪列表删除
$ git add file_new_name #重新添加命名后的文件到暂存区,并且标记被跟踪

注意:git命令中的“mv”并没有【移动】文件的功能,不像其他VCS系统或者Linux系统可以移动文件的位置。

1.5 撤销修改 UNDOING CHANGES

  • 反悔了-要重新提交
    要重新修改前一次提交的情况,比如要新建一个文件(新建后添加到暂存区),或要修改前一次提交的注解内容,或者需要增加提交几个文件,就可以执行下面命令:
$ git commit --amend #“撤销”前一次提交,重新完成提交操作,新提交操作会覆盖前一次提交

执行命令后会打开文件修改注解内容,默认是vi的方式。上面的命令可以理解为“撤销”前一次提交,重新完成提交操作,新的提交操作会覆盖前一次提交。

  • 取消暂存的文件
$ git reset HEAD file_name #对文件取消暂存,即取消“git add file_name”的操作。
  • 撤销对磁盘文件的修改
$ git checkout -- file_name 

危险!!上面的操作会直接撤销磁盘上该文件的所有修改,会回到上次提交的状态或刚放进工作目录样子。【分支】会很好的帮你处理类似的风险问题。
在Git中任何提交过的东西都几乎可以恢复,但是未提交的内容不会,所以涉及删除、撤销等操作是要格外地注意。

1.6 远程仓库 REMOTE REPOSITORIES

  • 查看本地相关联的远程仓库
$ git remote -v # 查看远程仓库名称和URL
$ git remote show [remote-name]  #查看详细信息
  • 添加远程仓库与本地仓库关联起来
$ git remote add 起个备注别名 远程仓库URL #今后可以使用备注别名代表这个远程仓库URL进行操作
  • 拉取远程仓库数据到本地仓库
$ git fetch [远程仓库备注别名(默认origin)或URL] #不会自动合并本地内容
$ git pull [远程仓库备注别名(默认origin)或URL] #会自动合并本地内容

注意git fetch仅仅是拉取远端仓库新的数据,并不会自动合并本地内容,需要手动今后合并,而git pull 则会自动合并。

  • 推送本地仓库到远程仓库
$ git push [remote_name] [branch_name]
  • 远程仓库重命名和移除
$ git remote rename old_name new_name #重命名远程仓库
$ git remote rm remote_name #移除远程仓库

1.7 别名

编辑config配置文件来完成别名的设置。

$ git config --global alias.别名名称 被替代的命令 #被替代的命令如果包含空格需要使用单引号把整个被替代的命令包含起来

举例:

$ git config --global alias.co checkout #设置后“co”等价于“checkout”
$ git config --global alias.br branch #设置后“br”等价于“branch”
$ git config --global alias.ci commit #设置后“ci”等价于“commit”
$ git config --global alias.st status #设置后“st”等价于“status”
$ git config --global alias.unstage 'reset HEAD --' #取消暂存,设置后“unstage”等价于“reset HEAD --”
$ git config --global alias.last 'log -1 HEAD' #使用last别名查看上一次提交记录

2 Git分支模型 GIT BRANCHES

每次提交都是一次完整的项目文件快照(以对象的形式),并非仅记录变化。每次提交到Git仓库后,都会创建三类对象:blog对象(文件快照对象)、树对象(记录目录结构和blog对象索引)、提交对象(记录提交信息、树对象索引和前一次提交对象/父对象索引)。Git分支,本质上就是仅仅指向提交对象的可变指针。所以创建分支,就只是创建一个可移动的指针。

2.1 分支操作

  • 创建、切换分支
$ git branch 分支名称 #创建分支

HEAD指针指向当前所在分支。创建新分支后,并不会自动切换到新分支上去,需要手动操作。

$ git checkout 分支名称 #切换到新分支,这样后HEAD就会指向切换的分支

如果想要创建分支并且马上切换过去,可以使用下面命令:

$ git checkout -b 新分支名字 #创建分支,并且切换过去
  • 删除分支
$ git branch -d 分支名称 #删除已合并的分支
$ git branch -D 分支名称 #强制删除分支(不管是否合并)
  • 合并分支
$ git merge 分支名字 #要先进入到想要合并到的分支,然后再把其他分支合并进来。可以把“master”合并到小分支上。

两个合并的分支中有一个是直接祖先时,会使用“fast-forward”快进合并,仅仅是把指针移动。如果不是直接祖先关系,公共祖先在更加久远的时刻,这时候要进行三方合并,Git会自动创建合并提交。

冲突解决:当两个不同的分支对同一个文件的同一个地方做了不同的修改,合并的时候就会出现冲突。此时需要使用【git status】查看冲突并手动去解决,然后再提交。

  • 分支管理
$ git branch #查看所有分支,仅提示分支名字。当前分支的最前面会有“*”号标记。
$ git branch -v #查看所有分支最近一次提交
$ git branch --merge #查看已经合并到当前分支的所有分支
$ git branch --no-merge #查看还没有合并到当前分支的所有分支

2.2 项目开发分支工作流

项目开发中常用分支策略:长期分支、特性分支、远程分支。

  • 长期分支
    保留主分支作为项目稳定版本,使用开发分支进行开发和维护。

  • 特性分支
    主分支是稳定版本,可以根据需要创建特性分支,完成特定的工作内容后可以随时删除。

  • 远程分支
    远程服务器上的分支。

$ git fetch origin #拉取远程服务器上origin仓库的数据到本地,并且更新本地数据库,使本地仓库与远程仓库一致
$ git merge origin/分支 #将从远程仓库拉取下来的内容,合并到当前分支

从一个远程跟踪分支检出一个本地分支,Git会自动创建一个叫做 “跟踪分支”。跟踪分支是本地分支,与远程分支有直接关系。如果在一个跟踪分支上输入git pull,Git 能自动地识别去哪个服务器上抓取、合并到哪个分支。

3 重写Git历史 REWRITING GIT HISTORY

建议:不要涉及任何已经推送到中央服务器的内容。

  • 修改最后一次提交
    要重新修改最后一次提交的情况,比如要新建一个文件(新建后添加到暂存区),或要修改前一次提交的注解内容,或者需要增加提交几个文件,就可以执行下面命令:
$ git add/rm 文件  #先进行修改
$ git commit --amend #然后“撤销”前一次提交,重新完成提交操作,新提交操作会覆盖前一次提交

执行上述操作需要注意,如果已经把提交的内容推送到远程服务器上面,就不要修正它(重新在前一次提交后的基础上再提交)。

  • 修改多个提交信息
    通过交互式的变基工具,指定要重写多久远的历史,完成操作。
$ git rebase -i HEAD~n #最后的n是数字,表示要修改最后的n次提交,“-i”为交互式操作。

注意上面的命令是变基操作,如果提交已经推送到服务器就不要执行,要保证所有内容都是在本地且尚未推送,不要涉及任何已经推送到中央服务器的提交(会出现一次变更的两个版本)。
执行上面命令后,根据提示输入相应的命令来完成修改。

  • 修改提交顺序
    命令和前一小节一样。
$ git rebase -i HEAD~n #最后的n是数字,表示要修改最后的n次提交,“-i”为交互式操作。

在打开的修改文件中,直接修改相应的提交顺序即可,还可以直接删除某个提交,当你完成操作保存文件的时候,所做的修改就会生效。
执行上面命令后,根据提示输入相应的命令来完成修改。

  • 压缩合并提交
    命令和前一小节一样。
$ git rebase -i HEAD~n #最后的n是数字,表示要修改最后的n次提交,“-i”为交互式操作。

第一行的命令关键字使用“pick”,其他行使用“squash”替代“pick”可以将所有的提交压缩到第一个提交来完成。
执行上面命令后,根据提示输入相应的命令来完成修改。

  • 拆分提交
    把一次提交拆分得更细,分几次来提交完成。
$ git rebase -i HEAD~n #最后的n是数字,表示要修改最后的n次提交,“-i”为交互式操作。

执行上面命令后,进入提交文件进行修改,要拆分的那个提交的“pick”命令改成“edit”,然后进行修改及add/commit操作,完成时运行“git rebase --continue”继续。

  • 修改所以提交历史
    “git filter-branch ”命令可以通过脚本的方式修改历史上大量的提交(危险操作!!慎重!)。可以从历史上所有提交中移除文件、让子目录作为新的根目录、全局修改邮箱地址等。
posted @ 2018-01-04 15:50  FEFJay  阅读(285)  评论(0编辑  收藏  举报