Git的使用及技巧

1、Git基础

1.1、版本管理

1.1.1、 什么是版本管理

版本管理是一种记录文件变化的方式,以便将来查阅特定版本的文件内容。

1.1.2、 人为维护文档版本的问题

  1. 文档数量多且命名不清晰导致文档版本混乱。
  2. 每次编辑文档需要复制,不方便。
  3. 多人同时编辑同一个文档,容易产生覆盖。

1.2、Git是什么

Git是一个版本管理控制系统(缩写VCS),它可以在任何时间点,将文档的状态作为更新记录保存起来,也可以在任何时间点,将更新记录恢复。

1.3、Git安装

官网下载即可-默认安装即可-安装后鼠标右键(默认使用比较多的是Git Bash Here)

  • git --version // 查看版本

1.4、Git基本工作流程

  1. git仓库:用于存放提交记录。
  2. 暂存区:临时存放被修改的文件。
  3. 工作目录:被Git管理的项目目录(我们写代码的地方)
  • 流程: 工作目录—>暂存区(git add ‘’)—>Git仓库(git commit -m ‘’)

1.5、Git的使用

1.5.1 、Git使用前配置

在使用git前,需要告诉git你是谁,在向git仓库中提交时需要用到。

  1. 配置提交人姓名: git config --global user.name ‘提交人姓名’
  2. 配置提交人邮箱:git config --global user.email ‘提交人邮箱’
  3. 查看git配置信息:git config --list
  • 注意⚠️:
    1、如果要对配置信息进行修改,重复上述命令即可。
    2、配置只需要执行一次。
    3、还可以直接通过.gitconfig配置文件进行修改。

1.5.2 、提交步骤

  1. git init 初始化git仓库(会在当前目录下生成.git文件夹,默认隐藏)
  2. git status 查看文件状态
  3. git add ‘文件列表’ 追踪文件(.或A 代表添加全部; 添加到暂存区中)
1、git add .:会监视工作区的状态树,使用它会把工作的所有变化提交到暂存区,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件。
2、git add -u:仅监控已经被add的文件(即track file),会将修改的文件提交到暂存区。add -u 不会提交新文件(untracked file)。(git add --update的缩写)
3、git add -A: 是上面两个功能的集合(git add --all的缩写)
总结:
git add -A: 提交所有的变化;
git add -u: 提交被修改(modified)和被删除(deleted)文件,不包括新文件(new);
git add .: 提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件。
  1. git commit -m ‘提交信息’ 向git仓库中提交代码(将暂存区的代码提交到git仓库中,最好每次提交只包含一个功能)
  2. git log 查看提交记录

1.5.3 、撤销

  • 用暂存区中的文件覆盖工作目录中的文件: git checkout ‘文件名字’ (在暂存中还是有)
  • 将文件从暂存区中删除: git rm --cached ‘文件’ (工作目录中还是会有)
  • 将git仓库中指定的更新记录恢复出来,并且覆盖暂存区和工作目录: git reset --hard commitID (之后的提交commit都会被删除)

2、Git进阶

2.1、分支

为了便于理解,大家暂时可以认为分支就是当前工作目录中代码的一份副本。使用分支,可以让我们从开发主线上分离出来,以免影响开发主线

2.1.1、分支细分

  1. 主分支(master):第一次向git仓库中提交更新记录时自动产生的一个分支。
  2. 开发分支(develop):作为开发的分支,基于master分支创建。
  3. 功能分支(feature):作为开发具体功能的分支,基于开发分支创建。
  4. 还有修复bug分支、存储不同依赖版本分支等

2.1.2、分支命令

  • git branch // 查看本地所有的分支
  • git branch -r // 查看所有远程的分支
  • git branch -a // 查看所有本地和远程分支
  • git branch ‘分支名’ // 创建分支(在哪个分支上操作,就是基于哪个分支创建新分支)
  • git checkout ‘分支名’ // 切换分支(切换分支前,当前分支上的更改一定要提交(commit)到git中-保持当前分支工作区完全干净。不然切换后的分支也会有更改内容。但可以用git stash命令暂时储藏)
  • git checkout -b dev // 创建开发分支dev,并切换到该分支下
  • git push --set-upstream origin branchname // 建立追踪关系,在现有分支与指定的远程分支之间
  • git merge ‘来源分支即被合并的分支dev’ // 合并分支,例dev合并到master(要先切换到要合并的分支master
  • git merge --abort 可以取消合并代码(代码合并了后发现有冲突,要取消合并可使用)(该命令仅仅在合并后导致冲突时才使用。git merge --abort将会抛弃合并过程并且尝试重建合并前的状态。但是,当合并开始时如果存在未commit的文件,git merge --abort在某些情况下将无法重现合并前的状态。特别是这些未commit的文件在合并的过程中将会被修改时。因此非常不鼓励在使用git merge时存在未commit的文件,建议使用git stash命令将未commit的文件,暂存起来。)
  • git branch -d ‘分支名’ // 删除分支(分支被合并后才允许被删除 -D强制删除)(不能在当前分支下删除当前分支

2.2、暂时保存更改

在git中,可以暂时提取该分支上所有的改动并储存,让开发人员得到一个干净的工作副本,临时转向其它工作。
使用场景:分支临时切换

  • 储存临时改动:git stash // 要先添加到暂存区中(git add ‘’)
  • 恢复临时改动:git stash pop
  • 注意⚠️:该操作是独立于分支的,即在其他分支也可以进行git stash pop。一旦恢复在剪切板上就不存在了

2.3、将分支上的一个单文件合并到主分支上

  1. 首先切换到主分支,注意将分支上的数据全部提交,以免造成数据冲突或丢失。
git checkeout master
  1. 选择要合并的分支、文件
git checkout --path '分支名称' '要合并的文件路径(文件在电脑中的全部路径)'
  1. 合并完成,提交
git add -A ''
git commit -m ''
git push
// 如果不想合并只是测试一定要回滚回来
git reset --hard origin/master 到上一个版本

2.4、从远程仓库读取过来并且覆盖本地仓库内容

git fetch 命令和可选项
git pull = git fetch+ git merge

// 1、fetch仓库中所有的分支。同时也会下载指定远端的所有commits和文件
git fetch <remote>
// 2、与上面命令相同,但是会fetch指定分支
git fetch <remote> <branch>
// 3、fetch所有已经注册过的远端仓库的全部分支
git fetch --all
// 4、--dry-run选项会执行fetch命令的演练,执行该命令的输出与执行正常fetch命令一致,但不会在本地应用这些更改。
git fetch --dry-run
// 5、确定没有问题之后,使用git merge origin/main合并远端变更
git merge origin/main
// 到此为止,origin/main分支和本地main分支都指向同一次commit,本地分支与远端分支同步完成。

git分为三部分workspace、index、repository;

  1. workspace:是指你的工作区域;
  2. index:是指本地的缓存,通过add操作将文件的更新添加至index;
  3. repository:是指本地的git仓库,这个仓库中的代码是通过commit添加的,push到远程仓库的代码也是这个位置的代码。
  • 所以git fetch更新的是repository部分的代码,workspace和index暂时还没更新。如果想要看到最新的代码,只需要在master(或其他响应的)分支上执行git merge指令,解决掉冲突再提交一遍就可以了。
  • git也提供了快捷指令git pull,可以直接用远程仓库的内容覆盖workspace的内容。但是不推荐这个指令,因为很可能会覆盖掉你尚未提交的更新。

git fetch命令总结

  • 总体来说git fetch是用于从远端仓库下载内容的主要命令。
  • git fetch与git remote,git branch,git check以及git reset命令结合使用,用来更新以及保证本地与远端的状态一致。
  • git fetch命令在git协作工作流中扮演着非常关键的角色。
  • git fetch命令与git pull命令行为类似,但被认为是更安全、非破坏性的更新同步命令。

3、Git实用命令

3.1、git stash和git stash pop

在切换分支时或者在开发过程要临时修改bug,为防止冲突或使工作区干净可使用此命令。

  1. git stash
    备份当前的工作区的内容,保存到git栈中,从最近的一次commit中读取相关内容。
  2. git stash pop
    • git栈中获取到最近一次stash进去的内容,恢复工作区的内容。获取后,会删除栈中对应的stash
    • 由于可能会stash多次,git使用栈管理(先进先出),我们可以使用git stash list 查看所有的stash。
  3. git stash list
    显示git栈中所有工作区内容的备份。
    比如使用git stash apply stash@{1},就可以把版本号为stash@{1}的备份取出,不会删除对应的stash。0为最新版本。
  4. git stash clear
    清空git栈。
  5. git stash show
    显示当前最新的改动,主要是恢复stash前可以看到修改的内容,如果忘记了stash什么内容可以使用,默认最新,如果要查看对应的stash用:git stash show $num
  6. git stash drop
    删除对应的stash,经常stash+stash pop一般不会用到drop命令,所以该命令使用比较少,如果需要一次性清空缓存区,可执行git stash clear
  7. git stash pop取出备份出现冲突问题
    比如,有个index.vue文件,你修改了一段代码,git stash保存后,从远程仓库继续git pull了别人的代码。如果别人也修改了index.vue代码。当我们使用git stash pop的时候,就会发生冲突,因为我们修改不是基于最新的pull下来的文件基础上,所以git很难判断。
    **解决方法:**备份我们修改后的文件,删除程序文件中我们所做的修改重新pull,然后再用我们备份好的文件替换掉,再push上去即可。
    另一种就是上面说的git reset --hard了,直接忽视本地修改。.
  8. git stash pop 和 git stash apply [] 的区别
    使用git stash命令之后会在stash列表中生成一个对应的信息,使用apply命令恢复,stash列表中的信息是会继续保留的,而pop命令进行恢复,会将stash列表中的信息进行删除

4、Git文件的四种状态

根据一个文件是否已加入版本控制,可以把文件状态分为:Tracked(已跟踪)Untracked(未跟踪),而tracked(已跟踪)又包括三种工作状态:Unmodified,Modified,Staged

  • Untracked:文件还没加入到git仓库,还没参与版本控制,即未跟踪状态。这时候的文件,通过git add 可以变为Staged状态
  • Unmodified:文件已经加入git库, 但是呢,还没修改, 就是说版本库中的文件快照内容与文件夹中还完全一致。Unmodified的文件如果被修改, 就会变为Modified. 如果使用git remove移出版本库, 则成为Untracked文件。
  • Modified:文件被修改了,就进入modified状态啦,文件这个状态通过stage命令可以进入staged状态。
  • staged:暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodified状态。

5、Git基本常用命令(流程)

  • git clone
    git clone url  克隆远程版本库 // 克隆远程版本库到本地
    
  • git checkout -b dev
    git checkout -b dev  // 创建开发分支dev,并切换到该分支下
    
  • git add
    git add .	// 添加当前目录的所有文件到暂存区git add [dir]	添加指定目录到暂存区,包括子目录git add [file1]	添加指定文件到暂存区
    
  • git commit
    git commit -m [message]  // 提交暂存区到仓库区,message为说明信息git commit [file1] -m [message] 提交暂存区的指定文件到本地仓库git commit --amend -m [message] 使用一次新的commit,替代上一次提交
    
  • git status
    当你忘记是否已把代码文件添加到暂存区或者是否提交到本地仓库,都可以用git status看
    git status  // 查看当前工作区暂存区变动git status -s  查看当前工作区暂存区变动,概要信息git status  --show-stash 查询工作区中是否有stash(暂存的文件)
    
  • git log
    git log,这个命令用得应该比较多,表示查看提交历史/提交日志~
    git log  查看提交历史git log --oneline 以精简模式显示查看提交历史git log -p <file> 查看指定文件的提交历史git blame <file> 一列表方式查看指定文件的提交历史
    
  • git diff
    git diff 显示暂存区和工作区的差异git diff filepath   filepath路径文件中,工作区与暂存区的比较差异git diff HEAD filepath 工作区与HEAD ( 当前工作分支)的比较差异git diff branchName filepath 当前分支的文件与branchName分支的文件的比较差异git diff commitId filepath 与某一次提交的比较差异
    
  • git pull/git fetch
    git pull  拉取远程仓库所有分支更新并合并到本地分支。git pull origin master 将远程master分支合并到当前本地分支git pull origin master:master 将远程master分支合并到当前本地master分支,冒号后面表示本地分支
    git fetch --all  拉取所有远端的最新代码git fetch origin master 拉取远程最新master分支代码
    
    我们一般都会用git pull拉取最新代码看看的,解决一下冲突,再推送代码到远程仓库的。
    有些伙伴可能对使用git pull还是git fetch有点疑惑,其实 git pull = git fetch+ git merge。pull的话,拉取远程分支并与本地分支合并,fetch只是拉远程分支,怎么合并,可以自己再做选择。
  • git push
    git push 可以推送本地分支、标签到远程仓库,也可以删除远程分支哦。
    git push origin master 将本地分支的更新全部推送到远程仓库master分支。
    git push origin -d <branchname> // 删除远程branchname分支
    git push --tags // 推送所有标签
    

6、Git的撤销和回退

Git的撤销与回退,在日常工作中使用的比较频繁。比如我们想将某个修改后的文件撤销到上一个版本,或者想撤销某次多余的提交,都要用到git的撤销和回退操作。
代码在Git的每个工作区域都是用哪些命令撤销或者回退的呢,如下图所示:
在这里插入图片描述
有关于Git的撤销与回退,一般就以下几个核心命令:

  • 1、git checkout
    如果文件还在工作区,还没添加到暂存区,可以使用git checkout撤销
    git checkout [file] 丢弃某个文件file
    git checkout . 丢弃所有文件

  • 2、git reset

    1. git reset的作用是修改HEAD的位置,即将HEAD指向的位置改变为之前存在的某个版本
    • 为了更好地理解git reset,我们来回顾一下,Git的版本管理及HEAD的理解:

    • Git的所有提交,会连成一条时间轴线,这就是分支。如果当前分支是master,HEAD指针一般指向当前分支,如下:
      在这里插入图片描述

    • 假设执行git reset,回退到版本二之后,版本三不见了哦,如下:
      在这里插入图片描述2. Git Reset的几种使用模式:
      在这里插入图片描述

    • 代码git add到暂存区,并未commit提交:
      git reset HEAD file 取消暂存
      git checkout file 撤销修改

    • 代码已经git commit了,但是还没有push:
      git log 获取到想要回退的commit_id
      git reset --hard commit_id 想回到过去,回到过去的commit_id

    • 代码已经push到远程仓库

      1. git log
      2. git reset --hard commit_id
      3. 把当前分支push到远程仓库并且让远程仓库和当前分支保持一致,使用如下命令(假定当前分支为master)
        git push -f origin master
        或 git push origin HEAD --force
  • 3、git revert
    与git reset不同的是,revert 复制了那个想要回退到的历史版本,将它加在当前分支的最前端
    在这里插入图片描述
    在这里插入图片描述

  • 如果代码已经推送到远程的话,还可以考虑revert回滚:
    git log 得到你需要回退一次提交的commit id。(git log -n 3。加上-n 3的话则只会打印最近3次提交)
    git revert -n <commit_id> 撤销指定的版本,撤销也会作为一次提交进行保存。
    在这里插入图片描述

7、Git的HEAD

HEAD 在 git 版本控制中代表头节点,也就是分支的最后一次提交,同时也是一个文件,通常在版本库中 repository/.git/HEAD,其中保存的一般是 ref: refs/heads/master 这种分支的名字,而本质上就是指向一次提交的 hash 值,一般长成这个样子 ce11d9be5cc7007995b607fb12285a43cd03154b。

  • HEAD指的就是==.git/HEAD文件,它储存着当前working directory所处的某次commit==,打开文件内容为:ref: refs/heads/master
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • refs目录下储存的是仓库和tags,每个仓库下又有分支,每个tags下又有tag,一个tag对应的某次commit。

    // 存储本地local master分支的最新commit对象的SHA-1
    refs/heads/master
    // 存储远程仓库master分支的最新commit对象SHA-1
    refs/remotes/origin/master
    // 存储tag的SHA-1
    tags/xxx
    
  • HEAD是当前分支引用的指针,它总是指向某次commit,默认是上一次的commit。这表示HEAD将是下一次提交的父节点。通常可以把HEAD看做你的上一次提交的快照。当然HEAD的指向是可以改变的,比如你提交了commit,切换了仓库,分支,或是回滚了版本,切换了tag等。

    • 如:在master分支上,一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点
    • 当新建分支时,如新建dev,dev会指向当前master分支的最近一次提交
    • 切换dev分支后HEAD就指向了当前分支dev了
    • 在dev上修改然后提交,分支dev指向当前分支的最新提交,而master指向master分支的最新提交
    • 切换为master,发现在dev上修改的master上并没有修改(此时HEAD还指向master分支的最近一次的提交)。
    • 把dev合并到master后,master指向了dev的最近一次提交。而HEAD指向当前分支即master。
  • HEAD~ 和 HEAD^

    回退到版本:git reset --hard HEAD~

    • HEAD^ 表示上一个版本 同 HEAD~1
    • HEAD^^ 表示上上个版本 HEAD~2(以此类推)
    • HEAD~100 表示上100个版本
    • HEAD~~、 HEAD^^、 HEAD~2、 HEAD^2
      在这里插入图片描述
         albert@home-pc MINGW64 /d/gitstart (dev1)
         $ git rev-parse --short HEAD~~
         dcdcb87
         albert@home-pc MINGW64 /d/gitstart (dev1)
         $ git rev-parse --short HEAD^^
          dcdcb87
         albert@home-pc MINGW64 /d/gitstart (dev1)
         $ git rev-parse --short HEAD~2
         dcdcb87
         albert@home-pc MINGW64 /d/gitstart (dev1)
         $ git rev-parse --short HEAD^2
         e330eac
      // 前三个表示方法是一样的,指向同一个提交记录,但是最后一个与他们不同,这时根据前面提到定义来看就行了,HEAD~~ 实际上是 HEAD~1~1的简写,而~ 后的数字就是指的后退的步数,所以 HEAD~~ 等价于 HEAD~2,属于一种合并计算。
      // HEAD^^ 是 HEAD^1^1 的简写,而 ^ 后面的数字表示后退一步到第几个父提交上,因为数字是1,所以 HEAD^^ 表示退一步到第一个父提交上,在退一步到第一个父提交上,这时与 HEAD~~ 的作用是相同的。
      // HEAD^2 就有些不同了,它表示后退一步到第二个父提交上,所以对照树形图是第二排的第二个节点。
      
    • HEAD~ 和 HEAD^ 后面都可以加数字。当数字大于1时则表现不一样,如上。HEAD~2 代表后退两步,每一步都后退到第一个父提交上,而 HEAD^2 代表后退一步,这一步退到第二个父提交上,如果没有第二个父提交就会报出以下错误:
      fatal: ambiguous argument ‘HEAD^2’: unknown revision or path not in the working tree.
      Use ‘–’ to separate paths from revisions, like this:
      ‘git […] – […]’

8、Git标签tag

  1. 什么是tag

    • tag主要用于版本库的一个标记,指向某个commit指针
    • tag主要用于发布版本的管理,一个版本发布后,我们可以为git打上v.1.0.1、v.1.0.2等这样的标签。
    • tag和branch(分支)有些相似,但本质和分工是不同的。
    • tag对应某次commit,是一个点,不可移动
    • branch对应的是一系列commit,是很多点连成的线,有一个HEAD指针,可以靠HEAD指针移动。
    • 所以,两者的区别决定了使用方式:改动代码用branch,不改动只查看用tag
    • tag 和 branch 的相互配合使用,有时候起到非常方便的效果,例如:已经发布了 v1.0 v2.0 v3.0 三个版本,这个时候,我突然想不改现有代码的前提下,在 v2.0 的基础上加个新功能,作为 v4.0 发布。就可以检出 v2.0 的代码作为一个 branch ,然后作为开发分支。
  2. tag的简单使用
    1、创建tag

    • 创建 tag 是基于本地分支的 commit,而且与分支的推送是两回事,就是说分支已经推送到远程了,但是你的 tag 并没有,如果把 tag 推送到远程分支上,需要另外执行 tag 的推送命令
    • git tag tagName //创建本地tag
    • git push origin tagName //推送到远程仓库
    • git push origin --tags // 若存在很多未推送的本地标签,你想一次全部推送的话
    • 以上是基于本地当前分支的最后的一个commit 创建的 tag ,但是如果不想以最后一个,只想以某一个特定的提交为tag ,也是可以的,只要你知道commit 的id。
    • git log --pretty=oneline //查看当前分支的提交历史 里面包含 commit id
    • git tag -a tagName commitId // 以某一个特定的提交为tag

    2、查看标签

    • git show tagName // 查看本地某个 tag 的详细信息
    • git tag 或者 git tag -l // 查看本地所有 tag
    • git ls-remote --tags origin // 查看远程所有 tag

    3、删除标签

    • git tag -d tagName // 本地 tag 的删除
    • git push origin :refs/tags/tagName // 远程 tag 的删除
         git tag -d 12345    #删除本地记录
         git push origin :refs/tags/12345    #删除远程记录
      
    • git push origin tagName // 把本地tag 推送到远端

    4、检出标签

    • git checkout -b branchName tagName
      因为 tag 本身指向的就是一个 commit,所以和根据commit id 检出分支是一个道理。
    • 但是需要特别说明的是,如果我们想要修改 tag检出代码分支,那么虽然分支中的代码改变了,但是 tag标记的 commit还是同一个,标记的代码是不会变的,这个要格外的注意。

    5、其它

    • 命令git tag -a tagname -m “XXX…” 可以指定标签信息。
    • 命令git tag -a v0.1.0 -m “release 0.1.0 version” 创建附注标签。
    • 命令git checkout [tagname] 切换标签。

9、Git其他

  • git reflog // 显示当前分支的最近几次提交
  • git blame filepath // git blame 记录了某个文件的更改历史和更改人,可以查看背锅人
  • git remote // 查看关联的远程仓库的名称
      git remote // 查看关联的远程仓库的名称
      git remote add url // 添加一个远程仓库
      git remote show [remote]  // 显示某个远程仓库的信息。
    
  • git rebase // rebase又称为衍合,是合并的另外一种选择。
    在这里插入图片描述
    rebase好处是: 获得更优雅的提交树,可以线性的看到每一次提交,并且没有增加提交节点。所以很多时候,看到有些伙伴都是这个命令拉代码:git pull --rebase,就是因为想更优雅

9.1、git pull和git fetch区别

在这里插入图片描述

  • git pull
    直接获取远程的最新提交,直接拉取并合并到本地工作目录,而且在合并过程中不会经过我们的审查,如果不仔细检查,这样很容易遇到冲突。
  • git fetch
    git fetch会首先检查本地仓库和远程仓库的差异,检查哪些不存在于本地仓库,然后将这些变动的提交拉取到本地。
    它是把远程提交拉取到本地仓库,而不是本地工作目录,它不会自行将这些新数据合并到当前工作目录中,我们需要继续执行git merge才会把这些变动合并到当前工作目录

git pull = git fetch + git merge。相比之下,git fetch是一个更安全的选择,因为它从你的远程仓库拉入所有的提交,但不会对你的本地文件做任何修改。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值