zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Git使用

2023-04-18 15:18:28 时间

Git

Git是一个分布式版本控制工具,用来管理多人写作的代码。同时也是一个内容管理系统

Git与SVN的区别:

  • Git是分布式的,svn不是。这是最核心的区别
  • Git把内容按元数据方式存储,而SVN是按文件:所有的资源控制系统都是把文件的原信息隐藏在一个类似.svn .cvs等的文件夹里
  • Git分支和SVN分支的不同:分支在SVN中一点都不特别,其实他就是版本库中的另外一个目录
  • Git没有一个全局的版本号,而SVN有
  • Git的内容完整性要优于SVN:Git的内容存储使用的是SHA-1哈希算法,这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏

1、Git安装

Windows平台上的安装,到官网https://gitforwindows.org/,下载安装包,一路确认,完成安装。

安装完成后,右键git bash here,可以使用命令行的git工具(自带SSH客户端)。

Git配置

Git提供了一个叫做git config的工具,专门用来配置或读取相应的工作变量。

这些环境变量,决定了Git在各个环节的具体工作方式和行为。这些变量可以存放在三个不同的地方:

  1. /etc/gitconfig 文件:系统中对所有用户都普遍使用的配置。若使用git config --system选项,读写的就是这个文件 D:smy_softwaregitGitetcgitconfig
  2. ~/.gitconfig:用户目录下的配置文件只适用于该永固。若使用git config --global选项,读写的就是这个文件。C:Users10170.gitconfig
  3. 当前项目的Git目录中的配置文件(也就是工作目录中的/.git/config文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以.git/config里的配置会覆盖/etc/gitconfig中的同名变量

项目路径/.git/config文件配置如下:

[core]
	repositoryformatversion = 0
	filemode = false
	bare = false
	logallrefupdates = true
	symlinks = false
	ignorecase = true
[remote "origin"]
	url = http://项目地址.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master

因为我使用过git config --global 命令配置过用户信息,所以这里使用的是2中的用户信息,这个文件里只记录了仓库的配置信息。

用户目录/.gitconfig配置信息

[user]
	email = 邮箱
	name = 用户名
[core]
	autocrlf = false

在 Windows 系统上,Git 会找寻用户主目录下的 .gitconfig 文件。主目录即 $HOME 变量指定的目录,一般都是 C:Documents and Settings$USER

此外,Git 还会尝试找寻 /etc/gitconfig 文件,只不过看当初 Git 装在什么目录,就以此作为根目录来定位。

配置用户信息

# 配置个人的用户名称和电子邮件地址
git config --global user.name "xxx"
git config --global user.email xxx@yy.com

如果使用了 --global选项,那么更改的配置文件就是位于用户主目录下的./gitconfig文件,以后所有的项目都会默认使用这里配置的用户信息。

如果要在某个特定的项目中使用其他名字或者电邮,只要去掉--global选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。

适用于工作项目和个人项目分开的场景。例如,在xxx/A目录我使用github账号远程我的github仓库,在xxx/B目录使用gitLab账号远程公司的gitLab仓库。

差异分析工具

经常用在解决合并冲突时使用差异分析工具。可以使用如下命令配置

# 改用vimdiff
git config --global merge.tool vimdiff

Git 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等合并工具的输出信息。

查看配置信息

检查已有的配置信息,可以使用如下命令

git config --list

注意:在idea中的终端中运行这个命令输出的信息是不完全的,需要在git bash中运行这个才可以看到完整的配置信息。

2、Git工作流程

一般工作流程如下:

  • 克隆 Git 资源作为工作目录。
  • 在克隆的资源上添加或修改文件。
  • 如果其他人修改了,你可以更新资源。
  • 在提交前查看修改。
  • 提交修改。
  • 在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。

如图所示
Git工作流程

3、Git原理

基本概念

我们先来理解下 Git 工作区、暂存区和版本库概念:

  • 工作区:就是你在电脑里能看到的目录。
  • 暂存区:英文叫 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 命令时,会直接从暂存区删除文件,工作区则不做出改变。
  • 当执行 git checkout . 或者 git checkout -- 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。
  • 当执行 git checkout HEAD . 或者 git checkout HEAD 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

4、Git基本操作

本地仓库与远程仓库

Git的工作就是创建和保存用户项目的快照及与之后的快照进行对比。

说明:

  • workspace:工作区
  • staging area:暂存区/缓存区
  • local repository:版本库或本地仓库
  • remote repository:远程仓库

创建仓库命令

命令 说明
git init 初始化仓库。
git clone 拷贝一份远程仓库,也就是下载一个项目。

一个文件夹成为一个git仓库的标志是,这个文件夹下有一个.git的隐藏文件夹。这个就是版本库,里面还有暂存区。这个文件夹下的其他文件作为被git管理的文件。

提交与修改

Git 的工作就是创建和保存你的项目的快照及与之后的快照进行对比。

下表列出了有关创建与提交你的项目的快照的命令:

命令 说明
git add 添加文件到暂存区
git status 查看仓库当前的状态,显示有变更的文件。
git diff 比较文件的不同,即暂存区和工作区的差异。
git commit 提交暂存区本地仓库
git reset 回退版本
git rm 将文件从暂存区工作区删除
git mv 移动或重命名工作区文件。

提交日志

命令 说明
git log 查看历史提交记录
git blame <file> 以列表形式查看指定文件的历史修改记录

远程操作

命令 说明
git remote 远程仓库操作
git fetch 从远程获取代码库
git pull 下载远程代码并合并
git push 上传远程代码并合并

5、Git分支管理

Git分支实际上是指向更改快照指针

当切换到一个分支的时候,Git会用此分支最后一次提交(commit)的快照替换掉工作区的内容。所以多个分支不需要多个目录。

命令 说明
git branch 查看所有的分支,并且高亮显示当前所在分支
git branch branchname 创建新分支,不切换到新分支。此时新分支指向工作区中的文件
git checkout branchname 切换到branchname分支
git checkout -b branchname 创建并切换到branchname分支,相当于前两条命令的组合。此时新分支指向工作区中的文件
git merge source 合并分支,将source分支合并到当前所在的分支。在git bash中默认不会删除原分支;在GitLab中默认勾选了Delete Source branch,会自动删除合并的source分支
git branch -d dev 删除dev分支,注意当前所在分支不能为dev分支,会报错。必须切换到其他分支再执行这个命令
git status 可以用来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件
git diff 显示合并冲突的地方

git merge的三种情况

  1. 快进(无冲突)
    • 描述:dev从master分支上创建,dev分支commit了多次后,并且master分支没有执行commit操作。
    • 此时,没有发生冲突,可以进行自动merge
    • 不会自动commit
  2. 非快进,修改不同文件(无冲突)
    • 描述:dev从master分支上创建,dev分支commit了多次后,master分支也提交了多次。并且两个分支修改的不是一个文件
    • 此时,没有发生冲突,可以进行自动merge
    • 合并后的版本,会自动commit一次
  3. 非快进,修改相同文件(有冲突)
    • 描述:dev从master分支上创建,dev分支commit了多次后,master分支也提交了多次。并且两个分支修改的是一个文件
    • 此时,会发生冲突,自动合并失败,需要手动解决冲突。
    • 使用命令git status 可以查看是哪些文件发生了冲突
    • 使用命令git diff 可以查看哪些文件的哪个地方发生冲突。
    • 手动打开这些文件,修改文件内容。vim
    • 手动提交 git add . git commit -m "xxx"

6、Git查看提交历史

Git 提交历史一般常用两个命令:

  • git log - 查看历史提交记录。
  • git blame <file> - 以列表形式查看指定文件的历史修改记录。
命令 说明
git log 查看提交记录,第一条是最新的
git log --oneline 查看历史记录的简洁版本
git log --graph 查看历史中什么时候出现了分支、合并。
git log --reverse --oneline 逆向显示所有日志
git log --author 查看指定用户提交的部分,如git log --author=Linus --oneline -5

7、Git标签

命令 说明
git tag -a v1.0 为最新一次的commit打上标签,-a表示创建一个带注解的标签。不用-a也可以创建标签,但是它不会记录标签是什么时候打的,谁打的,也不会添加标签的注解。
git tag 查看所有的标签
git tag -a v0.9 85fc7e7 为某个commit追加标签。与上面的区别是一个是为最新的commit打标签,这个是为指定的(可以不是最新的)commit打标签。

8、使用远程仓库

通过第三方的(github)或者自建的服务器,实现与其他人共同开发,版本控制。

远程仓库

命令 说明
git remote add [shortname] [url] 添加一个新的远程库,shortname一般为origin,url是远程仓库的地址。连接完成之后,可以将本地的commit push到远程仓库中。
git remote 查看当前配置有哪些远程仓库
git remote -v 查看当前配置有哪些远程仓库,显示url和方式
git fetch 从远程仓库下载最新分支与数据。该命令执行完后需要手动执行 git merge 远程分支到你所在的分支。
git pull <远程主机名> <远程分支名>:<本地分支名> 相当于git fetch 和 git merge的组合
git push origin <source>:<destination> 推送当前分支到远程分支
git remote rm [别名] 删除远程仓库

参考

  1. gitLab代码合并取消删除source分支
  2. git merge命令应用的三种情景