- 概述
本章节摘自菜鸟教程
原文链接:https://www.runoob.com/git/git-tutorial.html
-
- 简介
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
-
- Git与SVN区别
Git 不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。
如果你是一个具有使用 SVN 背景的人,你需要做一定的思想转换,来适应 Git 提供的一些概念和特征。
Git 与 SVN 区别点:
1、Git 是分布式的,SVN 不是:这是 Git 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最核心的区别。
2、Git 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn、.cvs 等的文件夹里。
3、Git 分支和 SVN 的分支不同:分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。
4、Git 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。
- Git 的内容完整性要优于 SVN:Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
- 基础概念
- 工作流程
注:此节为搬运菜鸟教程中的文章,搬运链接https://www.runoob.com/git/git-workflow.html
Git的一般工作流程如下:
1、克隆 Git 资源作为工作目录。
2、在克隆的资源上添加或修改文件。
3、如果其他人修改了,你可以更新资源。
4、在提交前查看修改。
5、提交修改。
6、在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。
下图展示了 Git 的工作流程:
-
- 工作区、暂存区与版本库
注:此节为搬运菜鸟教程中的文章,搬运链接https://www.runoob.com/git/git-workspace-index-repo.html
工作区:就是你在电脑里能看到的目录。
暂存区:英文叫stage, 或index。一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:
图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。
图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。
当对工作区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 "git rm --cached <file>" 命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行 "git checkout ." 或者 "git checkout -- <file>" 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
当执行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
- 常用命令
- git init
命令 |
解析 |
git init |
在本地将一个目录初始化为一个仓库 |
-
- git config
命令 |
解析 |
git config --list |
展示当前所有配置 |
git config --global user.name “<username>” |
配置全局username |
git config --global user.email “<email>” |
配置全局email |
-
- 生成ssh key
命令 |
解析 |
ssh-keygen -t rsa -C “<email>” |
1. 将生成的公钥添加进remote中,即可对该仓库该remote进行操作; 2. 可以使用cd ~/.ssh命令查看是否已经生成了ssh key; 3. windows系统中通常生成的ssh key文件位于C/用户/Administrator/.ssh路径下; |
-
- git clone
命令 |
解析 |
git clone <url> |
克隆获取远端仓库 |
git clone <url> -b <branch> |
克隆获取远端仓库的branch分支 |
-
- git remote
命令 |
解析 |
git remote add <name> <url> |
添加远端仓库,命名别名为<name> |
git remote -v |
查看添加的远端仓库详情列表 |
git remote remove <name> |
移除名为<name>的远端 |
git remote rename <old> <new> |
重命名 |
-
- git status
命令 |
解析 |
git status |
查看我们当前分支状态 |
-
- git branch
命令 |
解析 |
git branch |
查看当前仓库的分支列表及当前分支 |
git branch -m <oldbranch> <newbranch> |
重命名oldbranch为newbranch |
git branch -c <oldbranch> <newbranch> |
复制oldbranch并命名为newbranch |
git branch -d <branch> |
如果该分支已经合并到主分支,删除branch分支 |
git branch -D <branch> |
强制删除branch分支 |
git branch -m <oldname> <newname> git branch -m <newname> |
为分支改名,第一种适用于给任意分支改名,第二种适用于给当前分支改名 |
git branch -vv |
查看当前分支与远程跟踪分支的关系 |
git branch -a |
查看所有分支,包括本地和远程分支 |
git branch -r |
查看所有远程分支 |
git branch --set-upstream-to [remote]/[branch] |
将当前本地分支与给定的远端分支进行关联,remote是远端仓库名,branch是远端分支名,可以含/符号,例如 git branch --set-upstream-to origin/feature/xxxx |
-
- git add
命令 |
解析 |
git add . |
将当前分支下所有新建的未暂存的文件进行暂存,即状态变更为stage |
git add <target> |
将指定的目标进行添加暂存,这里的<target>既可以是文件,也可以是目录 |
git add -f <file> |
强制添加文件到stage,会绕过忽略规则 |
-
- git commit
命令 |
解析 |
git commit -m “<description>” |
将当前分支工作目录下所有状态为暂存的文件提交到该分支的版本库中 |
git commit --amend |
修改最近一次的提交记录 |
git commit -a |
提交所有的变动文件,相当于git add .和git commit的组合操作,但需要注意的是,这并不会暂存也不会提交新增的文件 |
-
- git fetch
命令 |
解析 |
git fetch <origin> <branch> |
从远端仓库下载代码到本地仓库对应的分支,此操作仅更新本地的版本库,而不会影响工作目录与暂存区 |
git fetch <origin> <branch>:<newbranch> |
从远端仓库的<branch>分支下载代码到本地仓库新建的<newbranch>分支 |
在更新时为了安全起见,可以按如下操作:
git fetch origin master:tmp //从远程仓库master分支获取最新,在本地建立tmp分支
git diff tmp //将当前分支和tmp进行对比
git merge tmp //合并tmp分支到当前分支
git branch -d temp //删除临时分支
或者:
git fetch orgin master //将远程仓库的master分支下载到本地当前branch中
git log -p master ..origin/master//比较本地的master分支和origin/master分支
git merge origin/master //进行合并
-
- git pull
命令 |
解析 |
git pull |
将远端仓库对应分支下载到本地,并直接merge到本地,相当于上述git fetch组合操作组合,因此此操作有一定风险,建议使用fetch,确认无误后再进行merge |
-
- git merge
命令 |
解析 |
git merge <targetbranch> -m <description> |
在本地版本库中将当前分支与目标分支合并 |
git merge <remote>/<branch> |
将本地分支与远程仓库中指定分支合并,但需要注意的是在使用此命令时,需要先执行下pull命令保证当前代码是最新的,否则无法正常合并,因为git在本地有一份各分支的清单,不pull更新的话它检测到本地目标版本号是旧的,所以直接提示代码为最新 |
-
- git push
命令 |
解析 |
git push --set-upstream <remote> <branch> |
将<branch>分支添加到<remote>远端对应仓库 |
git push |
将本地版本库中的变动提交到远端对应仓库对应分支中 |
git push [remote] [localbranch]:[remotebranch] |
将本地分支<localbranch>推送到远端<remote>的<remotebranch>分支上,如果远端<remotebranch>不存在,则会自动创建该分支,需要注意的是此操作不会将本地分支与远端分支进行关联 |
-
- git diff
命令 |
解析 |
git diff <branch> |
将当前分支和目标分支进行对比 |
-
-
- 对比结果分析
-
---代表源文件
+++代表目标文件
通常working area的文件都是被当作目标文件来看待。
-开头的行,是只出现在源文件中的行
+开头的行,是只出现在目标文件中的行
空格开头的行,是源文件和目标文件中都出现的行
差异按照差异小结进行组织,每个差异小结的第一行都是定位语句,由@@开头,@@结尾。
参考:https://blog.csdn.net/xx326664162/article/details/50926001
-
- git checkout
命令 |
解析 |
git checkout <branch> |
将当前工作区切换到<branch>分支,需要注意的是,此过程会导致未暂存的变动文件丢失 |
git checkout -- <file> |
将<file>文件切换到工作区中的版本 |
git checkout <id> -- <file> |
将<file>文件切换到某id版本 |
git checkout . |
用暂存区全部的文件替换工作区的文件 |
git checkout HEAD . git checkout HEAD <file> |
用 HEAD 指向分支中的全部或者部分文件替换暂存区和以及工作区中的文件 |
git checkout -b <newbranch> <remote>/<frombranch> |
从remote远端的frombranch分支拉取到本地并创建一个新的分支newbranch,并切换到该分支 |
-
- git reset
命令 |
解析 |
git reset HEAD |
暂存区的目录树会被重写,被head指向的分支目录树所替换,但是工作区不受影响,即上次commit的所有文件都会被取消提交 |
git reset <file> |
将某文件从暂存区移除,即取消提交某文件 |
-
- git clean
命令 |
解析 |
git clean -f |
强制清除所有未暂存的文件 |
git clean -fd |
强制清除所有未暂存的文件,包括目录 |
git clean -nfd |
预览即将清除的文件与目录 |
- 忽略文件
对于一些我们不需要提交的文件,每次提交时都会对我们的提交内容造成干扰,git提供了忽略机制,使用起来也非常简单,只需要在仓库目录下(与.git目录同级)创建.gitignore文件,在文件中配置忽略规则即可。
简单的忽略规则示例:
忽略目录:
*/target
*/.idea
忽略文件:
*.iml
- 查询代码量
- 查询个人时间段内代码量
git log --author="dongrui" --since=2020-01-01 --until=2020-01-31 --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -
-
- 查询个人时间段内提交次数
git log --author=dongrui --since="2014-07-01" --until=2014-08-31 --no-merges | grep -e 'commit [a-zA-Z0-9]*' | wc -l
-
- 查询时间段内所有人提交次数
git log --since=2020-03-01 --until=2020-03-31 | grep "^Author: " | awk '{print $2}' | sort | uniq -c | sort -k1,1nr
-
- 查询邮件格式账户时间段内提交代码量,升序排列
git log --format='%ae' | sort -u | while read email; do echo -en "$email\t"; git log --author="$email" --since="2020-03-01" --until="2020-03-31" --pretty=tformat: --numstat --stat | grep -E ".java|.xml|.yml|.sql" | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done
- 踩坑记录
- 账号切换问题
在使用中切换账号后发现无法正常使用,clone和fetch出现报错,报错信息提示CAPTCHA required
经过查找,发现是因为之前用其它账号登陆过,windows会记录下该网址的凭证,而之前的用户修改了密码,所以导致了上述错误,然后就在git中修改账户密码,但是无论在git中如何操作,都无法正常使用,最后发现是因为windows凭证不会被随git的用户密码改变,所以如果要切换账号,需要将这里的windows凭证删除。
控制面板-->用户帐户-->凭据管理器,找到对应网址的凭据然后删除。
感谢这个老外~~