Git实战_20171114

学习Git有一段时间了,一路上也一直在写有关于Git方面的文章,但总觉得不是我想要的,就是感觉有点肉肉的,不够直接,不够马上出效果,所以才有了这篇文章,当然这文章可能会不断更新和修正,希望读者可以作为一个工具文章使用,我也会努力将其优化的更加的符合工作场景

说明

1、在[...]中的内容,需要根据实际情况进行修改

[TOC]

说明

1、在[...]中的内容,需要根据实际情况进行修改

如何本地与远程建立信任联系?

要解决这个问题,需要使用SSH秘钥的方式,接下来我就讲一下怎么进行配置。

1.在本地生成私钥和公钥

git config --global user.name "username"//用户昵称
git config --global user.email "emailAddress"//github或者gitlib的邮箱地址
ssh-keygen -t rsa -C "emailAddress"//github或者gitlib邮箱账户地址

2.将电脑上的公钥与远程仓库进行绑定

本地会在上面的步骤中会生成一个id_rsa.pub(默认情况是这个名称),将该文件中的内容copy到远程仓库github或gitlib的settings的SSH配置选项中。

Tittle名称自由发挥

克隆工程

将远程的数据复制一份到本地

#【仓库copy地址】
git clone [[email protected]:zoeminghong/hello.git] [工程别名]

本地新建Git工程

现在打算将本地的工程,放到Git仓库进行托管了,并且远程Git仓库已经创建了该项目的工程

#本地初始化工程,会生成一个.git文件
git init
 
 
#将本地的工程与远程仓库中的项目进行关联(不用关心项目名不一致的问题)
#此时本地工程与远程仓库已经建立了联系
git remote add origin [[email protected]:zoeminghong/hello.git]
 
 
#将本地所有文件添加到Git中,进行监管
git add .
 
 
#将内容提交 【提交注释】
git commit -m "[...]"
 
 
#将本地的内容同步到远程仓库中
git push -u origin master

显示某一个特定的提交的日志

git show [十六进制码]

查看提交图

git log --graph --pretty=oneline --abbrev-commit

查看冲突未处理的文件列表

git ls-files -u

本地代码与远程代码冲突问题

本地代码未commit的前提下,解决与远程代码冲突问题

git pull #失败
#将当前修改进行暂存起来
git stash
#或
git stash save "[注释]"
 
#获取最新的远程仓库代码
git pull
 
#恢复暂存的内容
git stash pop

#stash其他操作
#恢复最近一次save的原工作区内容,,并删除stash记录
git stash pop
#恢复最近一次save的原工作区内容,但不删除stash记录
git stash apply [指定版本]
#删除stash记录
git stash drop
#获取暂存列表
git stash list

但,上面的也可能存在问题,由于本地存在未被追踪的文件,并且远程仓库pull的时候也存在同名的文件,就会存在pull失败,在这种情况下,在git stash后面追加 --include-untracked,会将远程的文件与本地的文件融合

stash只会保存当前索引和工作目录的状态,其保存的是add和commit的中间状态,如果还没有被git追踪的文件,是不会被记录的

如果我对某文件进行了修改,但我不想要push到远程仓库,同时我又想获取最新的修改记录

git stash save
git pull --rebase

如果暂存内容现在不想在当前分支恢复了,而是想单独起一个分支

git stash branch [newBranchName]

想要查看当前工作区与暂存状态内容区别

git stash show -p stash{0}

本地代码已经commit后,解决与远程代码冲突问题

# 获取远端库最新信息 【分支名称】
git fetch origin [master]
 
# 做比较
git diff [本地分支名] origin/[远程分支名]
 
# 拉取最新代码,同时会让你merge冲突
git pull

方法2

# 获取最新代码到tmp分支上 [远程的分支:本地分支]
git fetch origin [master:tmp]
 
 
# 当前分支与tmp进行比较
git diff tmp
 
 
# 修改冲突部分,进行本地commit操作
git add .
 
 
git commit -m "[...]"
 
 
# 将tmp中内容合并到当前分支中
git merge tmp
 
 
# 删除分支
git branch -d tmp

删除文件

保留副本操作

git rm --cache [文件名]

直接文件删除

git rm [文件名]

后悔药

存在5个记录状态

  • 未修改( Origin)

  • 已修改( Modified)

  • 已暂存( Staged)

  • 已提交( Committed)

  • 已推送( Pushed)

处于已修改,未暂存,还原到最近的版本,废弃本地做的修改(当前文件修改没有进行add操作的时候)

# 还原指定文件
git checkout -- [文件名]
# 还原所有
git checkout .
# 或
git reset --hard

取消已暂存未提交的文件(撤销先前"git add"的操作)

# 还原指定文件
git reset HEAD [文件名]
# 还原所有
git reset --hard

取消已提交未推送

#最近内容已经commit的情况下
git reset --hard origin/master

已推送

git reset --hard HEAD^
git push -f

回退到某个版本

# 获取所有的HEAD更改信息的sha1值
git reflog
git reset [SHA1]

回退到上一次提交的状态,按照某一次的commit完全反向的进行一次commit.(代码回滚到上个版本,并提交git)

git revert HEAD

使用reset是不会有日志记录的,revert则会要提交一个记录点

修改最新的提交信息(修改提交的注释信息)

git commit --amend

reset与revert的使用说明

reset一般用于本地还没有push到远端的时候,revert则用于想要远端也进行记录回退操作的时候,也就是说在push之后。

1、如果你已经push到远程仓库,reset删除指定commit以后,你git push可能导致一大堆冲突.但是revert 并不会

2、如果现有分支和历史分支需要合并的时候,reset 恢复部分的代码依然会出现在历史分支里.但是revert 方向提交的commit 并不会出现在历史分支里。

本地分支与远程分支相连

本地创建了一个分支,远程也有一个分支,进行两者关联

git checkout -b [本地分支名] origin/[远程分支名]

Tag使用

我们在开发的时候,可能存在线上发布了一个版本,需要给这个版本代码打上一个标签,到时候可以方便回退到这个版本

# 创建tag 【tag名】
git tag v1.0
(git tag -a [v1.4] -m ['my version 1.4'])
 
# 查看存在的tag
git tag
(git tag -l ['v1.4.2.*'])
 
# 将tag更新到远程,直接的push是不会将tag同步上去
git push origin --tags

接下来就讲解回退到具体的tag

# 保存当前编程环境
git stash
  
# 切换回某个tag(v1.0)
git show v1.0
 
#【sha1】
git reset --hard [2da7ef1]
  
# 创建分支来保存tag的数据,tag只是一个节点的标记,无法承载数据的修改记录,【分支名】
git checkout -b [branchName] [tagName] 
# 接着你就可以在这里改啊改了

切换回主干或其他分支

# 切换分支
git checkout master
 
# 日志记录
git reflog
 
# 显示stash列表
git stash list
 
# 恢复之前的工作环境代码
git stash apply
 
# 删除stash
git stash drop

分支与主干合并

git add .
git commit -m "v1.1"
git checkout [bill]
# master分支最新的代码合并到bill分支上
git rebase [master]
git checkout master
# bill分支合并到当前分支【分支名】
git merge [bill]

关于代码的比较

# 显示暂存区和工作区的差异
git diff
git diff [filename]
 
# 显示暂存区和上一个commit的差异【文件名】
git diff --cached [hello.txt]
git diff --cached [HEAD或者SHA1] [filename]
# 已提交远程仓库的差异
git diff master origin/master
# 显示工作区与当前分支最新commit之间的差异
git diff HEAD
git diff [HEAD或分支名] [filename]
 
# 显示两次提交之间的差异【分支名】
git diff [first-branch]...[second-branch]
git diff [SHA1] [SHA1] [filename]

#分支之间的差异
#分支之间的差异
git diff [分支1] [分支2]
git diff [分支1]..[分支2]
#指定文件
git diff [分支1]:[file1] [分支2]:[file2]

#查看指定提交范围内的所有变更文件情况
git diff --stat master~[范围值] [分支名]
git diff --stat master~5 tmp
//还可以值查看具体某一个文件
git diff --stat master~5 tmp test.txt

定位哪个提交点导致文件出现问题

#先确定范围
git bisect start
git bisect bad  #一般都是当前HEAD是坏提交【sha1】
git bisect good a794f9bd96f06b57b4c10433e4d6abb3f0855749 

#上面的步骤就是确定范围的,接下来就是回答git的问题,他指定的提交点是好的还是坏的
git bisect good//如果是坏的,就bad,直到你找到哪个提交点导致出现问题
#查看维护日志
git bisect log

git branch
#完成操作后,要回切到工作分支上
git bisect reset
git branch

git reset --hard fb47ddb2db...

检查文件中每一行代码是谁提交的记录

git blame -L [起始行数],[文件名]

创建分支

#以当前节点作为分支的开始起点
git branch [分支名]
#以SHA1作为分支开始起点
git branch [分支名] [SHA1]
#创建并切换分支,sha1以哪个节点作为分支的起点
git checkout -b [分支名] [SHA1]

拉去远程仓库分支代码

git checkout 1.0
git pull
#或者
git checkout 1.0 origin/1.0

开发的过程中生成新分支

#因可能存在未被git监管和未提交的内容,需要将未提交的内容进行监管和暂存
git add .
git stash
#包含[SHA1]及之前的代码会被copy盗分支上
git branch [分支名] [SHA1]

重命名分支

在git中重命名远程分支,其实就是先删除远程分支,然后重命名本地分支,再重新提交一个远程分支。

//显示现在分支
git branch -av
//删除远程要删除的分支devel
git push --delete origin devel
//重命名本地分支devel为develop
git branch -m devel develop
//推送到远程
git push origin develop

这是由于在 github 中,devel 是项目的默认分支。要解决此问题,这样操作:

  1. 进入 github 中该项目的 Settings 页面;

  2. 设置 Default Branch 为其他的分支(例如 master);

  3. 重新执行删除远程分支命令。

查看远程仓库分支

git branch -a

获取远程仓库分支代码

git fetch origin [远程仓库分支名] [本地仓库分支名]

删除本地分支

git branch -d [分支名]

删除远程仓库分支

git remote remove [分支名]

查看分支

git show-branch
#或
git branch

分支前面都存在*或者!

*表示当前分支

在–之后的是记录分支的提交信息

*+ [tmp] 远程2就表示该提交存在于两个分支中

显示某分支中某文件内容

git show [分支名]:[文件名]

显示某个节点某文件的内容

git show [SHA1] [文件名]

关于切换分支的逻辑

如果存在未被git追踪的文件,git是会将其忽略的

如果存在已追踪且被修改或删除,必须commit之后,才能切换

如果要不计后果的情况,强切,加-f

将当前的分支修改的内容同步到其他的分支上

假如你希望变更作用于另一个分支上,但由于当前分支如果不提交,是无法切换到另一个分支上的

git checkout -m [另一个分支名]

将一个区间的提交,移植到另一个分支

#当前分支,得到dev分支中dev~2之前的所有提交内容
git cherry-pick dev~2

cherry-pick会生成一条新的提交记录

代码行数统计

统计某人的代码提交量,包括增加,删除:

git log --author="$(git config --get user.name)" --pretty=tformat: --numstat | gawk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "added lines: %s removed lines : %s total lines: %s\n",add,subs,loc }' -

统计某人一个月内的代码提交量,包括增加,删除:

git log --since=1.month.ago --author="$(git config --get user.name)" --pretty=tformat: --numstat | gawk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "added lines: %s removed lines : %s total lines: %s\n",add,subs,loc }' -

仓库提交者排名前 5(如果看全部,去掉 head 管道即可):

git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 5

仓库提交者(邮箱)排名前 5:这个统计可能不会太准,因为很多人有不同的邮箱,但会使用相同的名字

git log --pretty=format:%ae | gawk -- '{ ++c[$0]; } END { for(cc in c) printf "%5d %s\n",c[cc],cc; }' | sort -u -n -r | head -n 5

贡献者统计:

git log --pretty='%aN' | sort -u | wc -l

提交数统计:

git log --oneline | wc -l

git log 参数说明:

--author 指定作者
--stat 显示每次更新的文件修改统计信息,会列出具体文件列表
--shortstat 统计每个commit 的文件修改行数,包括增加,删除,但不列出文件列表:
--numstat 统计每个commit 的文件修改行数,包括增加,删除,并列出文件列表:

-p 选项展开显示每次提交的内容差异,用 -2 则仅显示最近的两次更新

   例如:git log -p  -2

--name-only 仅在提交信息后显示已修改的文件清单
--name-status 显示新增、修改、删除的文件清单
--abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符
--relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)
--graph 显示 ASCII 图形表示的分支合并历史
--pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)

   例如: git log --pretty=oneline ; git log --pretty=short ; git log --pretty=full ; git log --pretty=fuller

--pretty=tformat: 可以定制要显示的记录格式,这样的输出便于后期编程提取分析

   例如:git log --pretty=format:""%h - %an, %ar : %s""
   下面列出了常用的格式占位符写法及其代表的意义。                   
   选项       说明                  
   %H      提交对象(commit)的完整哈希字串               
   %h      提交对象的简短哈希字串               
   %T      树对象(tree)的完整哈希字串                   
   %t      树对象的简短哈希字串                    
   %P      父对象(parent)的完整哈希字串               
   %p      父对象的简短哈希字串                   
   %an     作者(author)的名字              
   %ae     作者的电子邮件地址                
   %ad     作者修订日期(可以用 -date= 选项定制格式)                   
   %ar     作者修订日期,按多久以前的方式显示                    
   %cn     提交者(committer)的名字                
   %ce     提交者的电子邮件地址                    
   %cd     提交日期                
   %cr     提交日期,按多久以前的方式显示              
   %s      提交说明  

--since 限制显示输出的范围,

   例如: git log --since=2.weeks    显示最近两周的提交
   选项 说明                
   -(n)    仅显示最近的 n 条提交                    
   --since, --after 仅显示指定时间之后的提交。                    
   --until, --before 仅显示指定时间之前的提交。                  
   --author 仅显示指定作者相关的提交。                
   --committer 仅显示指定提交者相关的提交。
 
一些例子: git log --until=1.minute.ago // 一分钟之前的所有 log git log --since=1.day.ago //一天之内的log git log --since=1.hour.ago //一个小时之内的 log git log --since=`.month.ago --until=2.weeks.ago //一个月之前到半个月之前的log git

log --since ==2013-08.01 --until=2013-09-07 //某个时间段的 log git blame
看看某一个文件的相关历史记录

   例如:git blame index.html --date short

子模块

保留子组件的现有目录结构的完整性,故而git创造了类似于maven中的module一样的功能,来实现子模块的管理

打个比方:现在我有一个父工程A,其工程路径下面有五个子工程BCDEF,按照往常是要git clone 6个工程才可以完全下载成功,而且工程与工程之间的路径关系也不知道。现在有了gitmodules就可以直接下载A工程就可以了,其他的5个子工程都会自动下载。

文件.gitmodules存放在父工程根目录下

[submodule "others/B"]
    path = others/B
    url = https://rep.XXX.com/crm/B.git
[submodule "sources/C"]
    path = sources/C
    url = https://rep.XXX.com/crm/C.git
[submodule "sources/D"]
    path = sources/D
    url = https://rep.XXX.com/crm/D.git
.....

添加子模块

git submodules add [远程仓库地址] [相对于父模块的相对路径]

注:

直接手动更改gitmodule文件是没有用的哦

远程仓库地址要先于子模块之前准备好

子模块的名称是可以与[相对于父模块的相对路径]不一致的

创建完成以后会生成.gitmodules.gitattributes这两个文件

.gitmodules.git/config保存着子模块的信息

从远程仓库获取所有模块数据

#方式一
git clone --recursive [远程仓库地址]
#方式二
git clone [远程父仓库地址]
cd [父模块路径]
git submodule init
git submodule update
或者
git checkout [branchname]
git submodule update --init --recursive

删除子模块功能

先清空.gitmodules中的内容

再执行文件的删除

————

其他命令

# .gitmodules中子模块的内容更新到.git/config中
git submodule init

gitmodules参考

关闭issue

格式Fixes #45,45是issue的ID,在相应的issue的链接地址就有。

可以关闭issue的关键字:

  • close

  • closes

  • closed

  • fix

  • fixes

  • fixed

  • resolve

  • resolves

  • resolved

不同的仓库中关闭issue

格式close username/repository#issue_number

关闭多个issues

格式closes #34, closes #23, and closes example_user/example_repo#42

更多内容可以关注微信公众号,或者访问AppZone网站

你可能感兴趣的:(github,git)