Git教程

版本库

创建版本库

通过git init命令把目录变成Git可以管理的仓库

把一个文件放到Git仓库只需要两步:

第一步,用命令git add告诉Git,把文件添加到仓库:

git add readme.txt

执行上面的命令,没有任何显示,就对了。

第二步,用命令git commit告诉Git,把文件提交到仓库:

git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file1 file changed, 2 insertions(+)create mode 100644 readme.txt

简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

git commit命令执行成功后,1 file changed:1个文件被改动(我们新添加的readme.txt文件);2 insertions:插入了两行内容(readme.txt有两行内容)。

状态和差异【git status、git diff】

运行git status命令看看结果:

git status
On branch master
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git checkout -- <file>..." to discard changes in working directory)modified:   readme.txtno changes added to commit (use "git add" and/or "git commit -a")

git status命令可以让我们时刻掌握仓库当前的状态,上面的命令输出告诉我们,readme.txt被修改过了,但还没有准备提交的修改。

git diff这个命令看修改:

git diff readme.txt 

小结

  • 使用git status命令随时掌握工作区的状态。
  • 如果git status告诉你有文件被修改过,用git diff可以查看修改内容。

版本回退

在Git中,我们用git log命令查看历史记录。如果嫌输出信息太多,可以试试加上--pretty=oneline参数

git log --pretty=oneline
1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
e475afc93c209a690c39c13a46716e8fa000c366 add distributed
eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 wrote a readme file

把当前版本append GPL回退到上一个版本add distributed,就可以使用git reset命令(^的次数代表回退多少版本):

git reset --hard HEAD^

找到对应版本的commit id1094adb...,于是就可以指定回到未来的某个版本:

git reset --hard 1094a

Git提供了一个命令git reflog用来记录你的每一次命令:

git reflog
e475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
e475afc HEAD@{3}: commit: add distributed
eaadf4e HEAD@{4}: commit (initial): wrote a readme file

现在总结一下:

  • HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
  • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
  • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

工作区和暂存区

工作区(Working Directory)

就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区

版本库(Repository)

工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

image-20230718093939173

分支和HEAD的概念我们以后再讲。

前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:

  • 第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
  • 第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

撤销修改

git checkout -- file可以丢弃工作区的修改:

git checkout -- readme.txt

命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次git commitgit add时的状态。

git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。

一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm命令删了:

rm test.txt

这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了

  • 确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit

    git rm test.txt
    
  • 另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:

    git checkout -- test.txt
    

    git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

添加远程库

  1. 首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库

  2. 在Repository name填入learngit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库

  3. 根据GitHub的提示,在本地的learngit仓库下运行命令:

    git remote add origin git@github.com:【GitHub账户名】/【远程库名】.git
    
  4. 下一步,就可以把本地库的所有内容推送到远程库上:

    git push -u origin master
    
  5. 由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

删除远程库

如果添加的时候地址写错了,或者就是想删除远程库,可以用git remote rm <name>命令。使用前,建议先用git remote -v查看远程库信息:

git remote -v
origin  git@github.com:【GitHub账户名】/【远程库名】.git (fetch)
origin  git@github.com:【GitHub账户名】/【远程库名】.git (push)

然后,根据名字删除,比如删除origin

git remote rm origin

从远程库克隆

远程库已经准备好了,下一步是用命令git clone克隆一个本地库:

git clone git@github.com:【GitHub账户名】/【远程库名】.git

GitHub给出的地址不止一个,还可以用https://github.com/【GitHub账户名】/【远程库名】.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。

使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https

分支管理

创建与合并分支

理论过程
  1. 一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点‘

                      HEAD│▼master│▼
    ┌───┐    ┌───┐    ┌───┐
    │   │───▶│   │───▶│   │
    └───┘    └───┘    └───┘
    
  2. 每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。

  3. 当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev

                     master│▼
    ┌───┐    ┌───┐    ┌───┐
    │   │───▶│   │───▶│   │
    └───┘    └───┘    └───┘▲│dev▲│HEAD
    
  4. 不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变

  5. 假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并

  6. 合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支

实战过程
  1. 首先,我们创建dev分支,然后切换到dev分支:

    git checkout -b dev
    Switched to a new branch 'dev'
    
  2. git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

    git branch dev
    git checkout dev
    
  3. 然后,用git branch命令查看当前分支。git branch命令会列出所有分支,当前分支前面会标一个*号。

    git branch
    * devmaster
    
  4. dev分支的工作成果合并到master分支上。git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

    git merge dev
    Updating d46f35e..b17d20e
    ...
    
  5. 合并完成后,就可以放心地删除dev分支了:

    git branch -d dev
    Deleted branch dev (was b17d20e).
    

因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

switch

切换分支使用git checkout <branch>,而前面讲过的撤销修改则是git checkout -- <file>,同一个命令,有两种作用,确实有点令人迷惑。

实际上,切换分支这个动作,用switch更科学。因此,最新版本的Git提供了新的git switch命令来切换分支:

创建并切换到新的dev分支,可以使用:

git switch -c dev

直接切换到已有的master分支,可以使用:

git switch master

使用新的git switch命令,比git checkout要更容易理解。

小结

Git鼓励大量使用分支:

查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>或者git switch <name>

创建+切换分支:git checkout -b <name>或者git switch -c <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>

解决冲突

master分支和feature1分支各自都分别有新的提交,变成了这样

image-20230718103728357

这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突

git merge feature1Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

git status也可以告诉我们冲突的文件:

git statusOn branch master
Your branch is ahead of 'origin/master' by 2 commits.(use "git push" to publish your local commits)You have unmerged paths.(fix conflicts and run "git commit")(use "git merge --abort" to abort the merge)Unmerged paths:(use "git add <file>..." to mark resolution)both modified:   readme.txtno changes added to commit (use "git add" and/or "git commit -a")

Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,我们修改如下后保存

再提交:

git add readme.txt 
git commit -m "conflict fixed"
[master cf810e4] conflict fixed
image-20230718103936860

用带参数的git log也可以看到分支的合并情况:

git log --graph --pretty=oneline --abbrev-commit
*   cf810e4 (HEAD -> master) conflict fixed
|\  
| * 14096d0 (feature1) AND simple
* | 5dc6824 & simple
|/  
* b17d20e branch test

最后,删除feature1分支:

git branch -d feature1
Deleted branch feature1 (was 14096d0).

Bug分支

Git提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

git stash
Saved working directory and index state WIP on dev: f52c633 add merge

多人协作

  • 查看远程库信息,使用git remote -v
  • 本地新建的分支如果不推送到远程,对其他人就是不可见的;
  • 从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
  • 在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
  • 建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name
  • 从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

创建标签

在Git中打标签非常简单,首先,切换到需要打标签的分支上:

git branch
* devmaster
git checkout master
Switched to branch 'master'

然后,敲命令git tag <name>就可以打一个新标签:

git tag v1.0

可以用命令git tag查看所有标签:

git tag
v1.0

比方说要对add merge这次提交打标签,它对应的commit id是f52c633,敲入命令:

git tag v0.9 f52c633

还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:

git tag -a v0.1 -m "version 0.1 released" 1094adb

用命令git show <tagname>可以看到说明文字:

git show v0.1

如果标签打错了,也可以删除:

git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)

一次性推送全部尚未推送到远程的本地标签:

git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git* [new tag]         v0.9 -> v0.9

如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

git tag -d v0.9
Deleted tag 'v0.9' (was f52c633s)

小结

  • 命令git push origin <tagname>可以推送一个本地标签;
  • 命令git push origin --tags可以推送全部未推送过的本地标签;
  • 命令git tag -d <tagname>可以删除一个本地标签;
  • 命令git push origin :refs/tags/<tagname>可以删除一个远程标签。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/29282.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】进程间通信——管道/共享内存

文章目录 1. 进程间通信2. 管道匿名管道命名管道管道的特性管道的应用&#xff1a;简易的进程池 3. System V共享内存共享内存的概念共享内存的结构共享内存的使用代码实现 1. 进程间通信 进程间通信&#xff08;Inter-Process Communication&#xff0c;简称IPC&#xff09;是…

vue 集成tinymce2实现图片,视频以及文件的上传

vue 集成tinymce2实现图片&#xff0c;视频以及文件的上传 1. 安装插件 &#xff08;1&#xff09;安装tinymce npm install tinymce -S &#xff08;2&#xff09;安装tinymce-vue npm install tinymce/tinymce-vue3.0.1 -S 2. 复制静态文件到public目录 资源下载路径&…

【116个】网络安全测试相关面试真题

1、Burpsuite常用的功能是什么&#xff1f; 2、reverse_tcp和bind_tcp的区别&#xff1f; 3、拿到一个待检测的站或给你一个网站&#xff0c;你觉得应该先做什么&#xff1f; 4、你在渗透测试过程中是如何敏感信息收集的&#xff1f; 5、你平时去哪些网站进行学习、挖漏洞提交到…

git rebase 合并提交

一. 合并提交步骤 git log --oneline 查看当前提交记录 git rebase -i HEAD~2 选择最后提交的2条记录进行合并进入编辑界面,将c865404的pick改为f, 表示向前合并也就是向cc5a54合并 编辑完之后:wq 保存并退出git rebase --continuegit push --force origin feature/v1.2 推送…

Python venv 和 virtualenv 虚拟环境的基本使用

1.前言 venv 和 virtualenv 都是搭建虚拟环境的工具&#xff0c;virtualenv 是第三方开源的&#xff0c;而 venv 作为 virtualenv 的一个子集自 Python3.3 开始集成到标准库中&#xff0c;在 virtualenv 的文档中可以看到他们的区别&#xff1a; 没有 app-data 种子方法&#…

WEB APIs day4 (1)

一、日期对象 1.实例化 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevi…

MySQL(十):MySQL语法-进阶

MySQL语法-进阶 数据类型Text 类型Number 类型Date 类型 ASALTER TABLEconcat、group_concatSQL注入阻止SQL注入方案一方案二方案三 HAVING 子句临时表正则表达式获取服务器元数据事务导出数据导出数据导出表作为原始数导出SQL格式的数据 导入数据解决无法导入问题使用 LOAD DA…

VS工程项目中属性中无Qt设置问题解决方案

VS工程项目中属性中无Qt设置问题解决方案 若VS工程中&#xff0c;创建的是Qt工程&#xff0c;或者从Qt Creator工程转换为VS 工程时&#xff0c;VS项目属性中确无Qt Project Setttings等设置时&#xff0c;可通过如下方案解决 1. 右键项目&#xff0c;在下拉框中选择Qt项 2.…

肯尼亚税务局如何利用RPA、AI等创新技术来推动税务合规增加税收?

在当今的数字化时代&#xff0c;税务部门的工作变得日益复杂。依赖手动程序为税务部门带来了巨大的困难&#xff0c;这使得在有效管理税收和实现收入目标上遇到了阻碍。手动流程往往效率低下&#xff0c;易出错&#xff0c;而且难以应对大规模的数据处理需求。如果不能解决该问…

Spring MVC相关注解运用 —— 中篇

目录 一、RESTful风格支持 1.1 RESTful风格介绍 1.2 postman使用 二、PathVariable 2.1 实例程序 2.2 测试结果 三、PostMapping、GetMapping、PutMapping、DeleteMapping 四、HiddenHttpMethodFilter 4.1 在web.xml配置过滤器 4.2 控制器方法 4.3 JSP页面 4.4 测…

Docker 仓库与注册表: 构建可靠的容器镜像生态系统

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

使用NVIDIA FX Composer验证多纹理合成效果

最近项目上有一个需求&#xff0c;需要将4张带透明通道纹理合成为一张&#xff0c;并且每张纹理指定一个全局透明度。由于纹理过多&#xff0c;合成效果无法保证&#xff0c;为了减少项目的风险&#xff0c;领导希望我先快速验证一下我们讨论的方法是否能完成项目的要求。因此我…