您现在的位置是:首页 >其他 >详版Git命令播报网站首页其他

详版Git命令播报

定栓 2023-05-28 12:00:02
简介详版Git命令播报

Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。

下载安装

Git 各平台安装包下载地址为:http://git-scm.com/downloads

官网慢,可以用国内的windows镜像:https://npm.taobao.org/mirrors/git-for-windows/

Git 配置

config文件

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

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

  • /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。看当初 Git 装在什么目录,就以此作为根目录来定位,笔者目录为 C:/Program Files/Git/etc/
  • ~/.gitconfig 文件:用户目录下的配置文件,只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。在 Windows 系统上,用户目录目录一般为 C:/Users/userName
  • 当前项目的 Git 目录中的配置文件(也就是工作目录中隐藏文件夹 .gitconfig 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。

配置用户信息

配置个人的用户名称和电子邮件地址:

git config --global user.name "caoyuan"
git config --global user.email test@caoyuan.com

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

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

也可以编辑 git 配置文件:

在window系统上先设置config文件默认使用notepad打开

git config core.editor notepad

git config -e 针对当前仓库 `

git config -e --global 针对当前系统登录用户所有仓库

查看配置信息

要检查已有的配置信息,可以使用 git config --list 命令。

在命令行出现 (END) 时,可以按 q 键退出

git config --list

diff.astextplain.textconv=astextplain
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
http.sslbackend=openssl
http.sslcainfo=C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
core.autocrlf=true
core.fscache=true
core.symlinks=false
pull.rebase=false
credential.helper=manager-core
...

有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig~/.gitconfig),不过最终 Git 实际采用的是最后一个

也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:

git config user.name

caodingshuan

工作协作流程

git四个区

  • Workspace工作区,就是你平时电脑里存放项目代码的地方。
  • Index / Stage暂存区,用于临时存放你的改动,一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index),保存即将提交的文件列表信息。
  • Repository仓库区(或版本库),就是安全存放数据的位置(隐藏目录 .git),这里面有你提交的所有版本的数据。其中HEAD指向最新放入仓库的版本(指向你最后一次提交的结果)。
  • Remote远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换。

协作流程

一般协作流程如下:

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

下图展示了 Git 的协作流程:

初始化新仓库

创建新文件夹或使用一个已经存在的目录作为 Git 仓库。打开,然后执行 git init 来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行。

在执行完成 git init 命令后,Git 仓库会生成一个 .git 隐藏目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。可以使用linux命令ls -a或者dos命令dir /a查看。

也可以使用指定目录作为Git仓库。

git init newrepo

如果当前目录下有几个文件想要纳入版本控制,需要先用 git add 命令告诉 Git 开始对这些文件进行跟踪,然后提交:

git add *.c
git add README.md
git commit -m "初始化项目版本"

以上命令将目录下以 .c 结尾及 README.md 文件提交到本地仓库中。

在 Linux 系统中,commit 信息使用单引号('),Windows 系统,commit 信息使用双引号(")

所以在 git bash 中 git commit -m '提交说明' 这样是可以的。

在 Windows 命令行中就要使用 git commit -m "提交说明"

检出仓库

git clone

我们使用 git clone 从现有 Git 仓库中拷贝项目。此方式适用于本地没有项目代码情况,直接从头开始完整克隆一个代码仓库。

克隆仓库的命令格式为:

git clone <repo>

如果我们需要克隆到指定的目录,可以使用以下命令格式:

git clone <repo> <directory>

参数说明:

  • repo: Git 仓库。
  • directory: 本地目录。

比如,要克隆 Git 代码仓库 pinia,可以用下面的命令:

git clone https://github.com/vuejs/pinia.git

执行该命令后,会在当前目录下创建一个名为pinia的目录,其中包含一个 .git 的目录,用于保存下载下来的所有版本记录。

如果要自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:

git clone https://github.com/vuejs/pinia.git mypinia

git clone支持多种协议,除了 HTTP(s) 以外,还支持 SSHGit本地文件协议 等,下面是一些例子。

git clone http[s]://example.com/path/repo.git
git clone ssh://example.com/path/repo.git
git clone git://example.com/path/repo.git
git clone ftp[s]://example.com/path/repo.git
git clone D:/opt/git/project.git 
git clone file:///opt/git/project.git
git clone rsync://example.com/path/repo.git

执行如下命令以创建一个本地仓库的克隆版本:

git clone D:companyprojectxxx

通常来说,https协议下载速度最快,SSH协议用于需要用户认证的场合。各种协议优劣的详细讨论请参考官方文档。

报错处理:

运行clone命令时,报错 Could not resolve host: github.com

可以先命令行输入 ping github.com,然后获取响应的IP,笔者这里获得的是20.205.243.166。

编辑系统文件 etc/hosts,位置为 C:WindowsSystem32driversetc,添加了下图语句,

20.205.243.166 github.com

重新运行,最后获取成功。

git remote

为了便于管理,Git要求每个远程主机都必须指定一个主机名。git remote 命令就用于管理主机名。

不带选项的时候,git remote命令列出所有远程主机。

git remote

输出:origin

使用 -v 选项,可以参看远程主机的网址。

git remote -v

输出:
origin  https://github.com/vuejs/pinia.git (fetch)
origin  https://github.com/vuejs/pinia.git (push)

上面命令表示,当前只有一台远程主机,叫做origin,以及它的网址。

克隆版本库的时候,所使用的远程主机自动被Git命名为origin。如果想用其他的主机名,需要用 git clone 命令的 -o 选项指定。

git clone -o pinia https://github.com/vuejs/pinia.git
cd pinia
git remote

输出:pinia

上面命令表示,克隆的时候,指定远程主机叫做 pinia

  • git remote show [<主机名>|<主机地址>] 可以查看该主机的详细信息

    git remote show pinia
    或
    git remote show https://github.com/vuejs/pinia.git
    
    输出:
    * remote pinia
    Fetch URL: https://github.com/vuejs/pinia.git
    Push  URL: https://github.com/vuejs/pinia.git
    HEAD branch: v2
    Remote branches:
      docs/animated-pinia     tracked
      docs/wwads              tracked
      feat/strict-mode        tracked
      fix/tree-shake-devtools tracked
    ...
    
  • git remote add <主机名> <网址> 用于添加远程主机,主机名为本地的版本库

    git remote add origin1 https://github.com/vuejs/pinia.git
    
    git remote
    
    输出:
    origin1
    pinia
    
  • git remote rm <主机名> 命令用于删除远程主机。

    git remote rm origin1
    
    git remote
    
    输出:pinia
    
  • git remote rename <原主机名> <新主机名>命令用于远程主机的改名。

    git remote rename pinia piniachanged
    
    输出:Renaming remote references: 100% (11/11), done.
    
    git remote
    
    输出:piniachanged
    

本地存有代码进行clone

以下两种方式的前提是需要在远程建立一个空仓库,并获取代码仓库地址。

没有git仓库

mkdir emptyrepository
cd emptyrepository
git init 
echo readme>README.md
git add README.md
git commit -m "first commit" // 到这一步,本地会出现当前所在的master分支
git remote add origin https://gitee.com/caodingshuan/emptyrepository.git
git push -u origin "master"

已存在git仓库

cd existing_git_repo
git remote rm origin // 删除远程同名主机名
git remote add origin https://gitee.com/caodingshuan/emptyrepository.git
git push -u origin "master"

提交与修改

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

git add 及 git status

  • git add 命令可将该文件添加到暂存区。

    • git add file1Name file2Name ...: 添加一个或多个文件到暂存区。
    • git add dirName:添加指定目录到暂存区,包括子目录。
    • git add .: 添加当前目录下的所有文件到暂存区。
  • git status 命令用于查看在你上次提交之后是否有对文件进行再次修改。

    • git status -s: 获得简短的输出结果,-s(--short缩写)

执行 git add 命令来添加文件:

git add file.ts render.vue 

执行 git status 命令,查看项目文件的当前状态,可以看到这两个文件已经加上去了

git status

输出:
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   file.ts
        new file:   render.vue

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        doc/

现在我们执行 git status -s 命令来获得简短的输出结果。

git status -s
A  file.ts   
A  render.vue
?? doc/     

我们将doc目录下的文件添加到暂存区。

git add doc

现在我们再执行 git status -s,可以看到doc目录下的文档及子目录下的文档均添加到暂存区。

git status -s

输出:
A  doc/childDoc/read2.pdf
A  doc/read1.pdf
A  file.ts
A  render.vue

当然我们可以使用 git add . 命令来添加当前项目的所有改动文件到暂存区。

现在我们修改 file.ts 文件:

再执行一下 git status -s

git status -s

输出:
A  doc/childDoc/read2.pdf
A  doc/read1.pdf
AM file.ts
A  render.vue

AM 状态的意思是这个文件在我们将它添加到暂存区之后又有改动。改动后我们再执行 git add . 命令将其添加到暂存区中:

git diff

git diff 命令比较文件的不同,即比较文件在工作区暂存区、**最后一次提交(commit)**之间的不同。

  • git diff [file]:工作区和暂存区的差异
  • git diff --cached [file]git diff --staged [file]:显示暂存区和上一次提交(commit)的差异
  • git diff HEAD:查看工作区和暂存区文件改动与上一次提交(commit)的差异
  • git diff --stat:显示摘要而非整个 diff
  • git diff [first-branch]...[last-branch]git diff [first-commit]...[last-commit]:显示两(多)个分支或两(多)次提交之间的差异

我们对项目test.md文件进行修改,输入git diff命令,对比工作区和暂存区的差异。

git diff

输出:
diff --git a/test.md b/test.md
index d800886..8020981 100644 
--- a/test.md
+++ b/test.md
@@ -1 +1,3 @@
-123
+md文件修改行1
+md文件修改行2
+md文件修改行3

这时候我们输入git status查看下文件状态

git status -s
 
输出:M test.md

可以看到git status 显示你上次提交更新后的更改或者写入缓存的改动, 而 git diff 一行一行地显示这些具体的改动。

输入git add .将文件从工作区添加到暂存区,我们输入git diff --cached命令,显示暂存区和上一次提交(commit)的差异

git add .

git diff --cached

输出:
diff --git a/test.md b/test.md
index d800886..8020981 100644 
--- a/test.md
+++ b/test.md
@@ -1 +1,3 @@
-123
+md文件修改行1
+md文件修改行2
+md文件修改行3

修改项目test.js文件,输入git diff HEAD命令查看已缓存的与未缓存的所有改动

git diff HEAD

输出:
diff --git a/test.js b/test.js
index ae064d9..e969625 100644 
--- a/test.js
+++ b/test.js
@@ -1 +1,3 @@
-好人是好人
+js文件修改行1
+js文件修改行2
+js文件修改行3
diff --git a/test.md b/test.md
index d800886..8020981 100644
--- a/test.md
+++ b/test.md
@@ -1 +1,3 @@
-123
+md文件修改行1
+md文件修改行2
+md文件修改行3

我们可以输入git diff HEAD --stat来显示摘要而非整个 diff

git diff HEAD --stat

输出;
test.js | 4 +++-
test.md | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)

我们也可以对比不同分支和不同提交。

  1. 我们先在master分支创建branch.txt文件,文本内容为当前分支名称master,修改后提交。
  2. 随后我们创建sit分支,修改branch.txt文件内容为sit,随后提交。
  3. 最后我们创建dev分支,修改branch.txt文件内容为dev。并提交。

我们先进行分支的对比

git diff dev sit master 

输出:
diff --cc branch.txt
index 5c31fb8,8b25206..9001211
--- a/branch.txt
+++ b/branch.txt
@@@ -1,1 -1,1 +1,1 @@@
- sit
 -master
++dev

再进行commit hash进行对比

git diff fad3a22bad4d2d2b6784c84c16189c2615b710c0 8c17f68e8c3b9c480937e18fb9718821b3ab67aa b7846a78bd43dc3e03bd16027a4701c1c1198292

输出:
diff --cc branch.txt
index 5c31fb8,8b25206..9001211
--- a/branch.txt
+++ b/branch.txt
@@@ -1,1 -1,1 +1,1 @@@
- sit
 -master
++dev

可以看到输出顺序是,最后创建的dev分支的内容与随后的分支逐个进行对比。提交(commit)对比同理。

git commit

前面我们使用 git add 命令将内容写入暂存区。现在我们使用git commit 命令将暂存区内容添加到本地仓库中。

  • git commit -m [message]: 提交暂存区到本地仓库中,message 可以是一些备注信息。
  • git commit [file1] [file2] ... -m [message]:提交暂存区的指定文件到仓库区
  • git commit -am [message]-a 参数设置修改文件后不需要执行 git add 命令,直接来提交

修改项目中test.js文件,提交

git add .
git commit -m "测试1"

输出:
[master cbf85e6] 测试1
 1 file changed, 1 insertion(+), 1 deletion(-)

指定test.js文件提交

git add .
git commit test.js -m "测试2"

输出:
[master d969071] 测试2
 1 file changed, 1 insertion(+), 1 deletion(-)

查看下文件状态

git status

输出:
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

以上输出说明我们在最近一次提交之后,没有做任何改动,是一个 “working tree clean”,翻译过来就是干净的工作目录。

如果你觉得 git add 提交缓存的流程太过繁琐,Git 也允许你用 -a 选项跳过这一步。

git commit -am "测试3"

输出:
[master eaffe72] 测试3
 1 file changed, 1 insertion(+), 1 deletion(-)

如果你没有设置 -m 选项,Git 会尝试为你打开一个编辑器以填写提交信息。

打开的文档如下,需要输入此次提交的信息

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Your branch is up to date with 'origin/master'.
#
# Changes to be committed:
#	modified:   test.js
#

git reset

git reset [ --mixed | --soft | --hard ] [ HEAD ]:用于回退版本,可以指定退回至某一次提交的版本。

  • --mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,并将之前修改后提交到暂存区的文件回退到工作区,且之前工作区文件内容将与回退的版本内容进行合并。

    git reset HEADgit reset 命令用于取消已缓存的内容,使其回退至工作区。也可以回退指定的缓存区文件git reset test.js

    实例:

    git reset HEAD^          # 回退内容至上一个版本。
    git reset c856725         # 回退到指定版本。
    git reset c856725 test.js  # 回退 test.js 文件到指定版本。
    

    当命令行出现 More?,则输入几个^,表示回退几个版本。

    回退内容至特定版本后,工作区中的文件包含该特定版本之后的文件内容改动(不包含该特定版本内容改动)。

  • --soft 参数用于回退到某个版本。回退带来的改动内容将自动放置在暂存区,并进行合并。工作区文件内容不受影响。

    git reset --soft HEAD
    

    实例:

    git reset --soft HEAD~3   # 回退上上上一个版本 
    
  • --hard 参数撤销工作区与暂存区中所有未提交的修改内容,并将本地文件内容回退到指定版本。

    git reset --hard HEAD
    

    实例:

    git reset --hard HEAD~3  # 回退上上上一个版本  
    git reset –hard c856725  # 回退到指定版本。 
    git reset --hard origin/master    # 将本地的文件状态回退到和远程的一样。 
    

    注意:谨慎使用 –-hard 参数,它会删除所有未提交的内容。

HEAD 说明

HEAD 表示当前版本

HEAD^ 上一个版本

HEAD^^ 上上一个版本

HEAD^^^ 上上上一个版本

以此类推…

也可以使用 数字表示

HEAD~0 表示当前版本

HEAD~1 上一个版本

HEAD~2 上上一个版本

HEAD~3 上上上一个版本

以此类推…

git rm

git rm 命令用于删除文件。

  • git rm <file>:将文件从暂存区和工作区中删除。即将文件在工作区中删除,并将改动自动提交到暂存区。

    删除下项目中test.js文件

    git rm test.js
    
    输出:rm 'test.js'
    

    查看下文件状态

    git status
    
    输出:
    On branch master
    Your branch is up to date with 'origin/master'.
    
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            deleted:    test.js
    

    如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f

    强行从暂存区和工作区中删除修改后的 test.js 文件。即删除后,工作区文件会消失,同时暂存区会保留文件删除更改。

    git rm -f test.js
    
  • git rm --cached <file>:把文件从暂存区域移除,但仍然保留在当前工作目录中,换句话说,仅是从跟踪清单中删除。

    将提交到暂存区的test.js文件进行移除

    git rm --cached test.js
    
    输出:rm 'test.js'
    

    查看文件状态

    git status
    
    输出:
    On branch master
    Your branch is up to date with 'origin/master'.
    
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            deleted:    test.js
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
            test.js
    
  • git rm –r dirName :可以递归删除,即如果后面跟的是一个目录做为参数,则会递归删除整个目录中的所有子目录和文件。

    进入某个目录中,执行git rm –r *,会删除该目录下的所有文件和子目录。

注意:如果是新创建的文件夹及文件,则需要先将文件添加到暂存区,使之在git控制之下,再添加-f参数进行删除。

即先执行git add .,删除目录则执行git rm -r -f dirName,进入目录执行git rm -r -f *则删除该目录下所有文件和子目录。

git mv

git mv 命令用于移动或重命名一个文件、目录或软连接。

git mv [file] [newfile]:重命名文件

对test.js文件重命名为testtest.js文件

git mv test.js testtest.js

git status

输出:
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        renamed:    test.js -> testtest.js

如果新文件名已经存在,但还是要重命名它,可以使用 -f 参数:

git mv -f [file] [newfile]

将testtest.js重命名为branch.txt(项目中已有文件)。则看到testtest.js文件内容覆盖到branch.txt文件,同时中间文件testtest.js被删除。从追踪关系来看,即最开始的test.js文件被删除,同时将内容覆盖到branch.txt文件。

git mv -f testtest.js branch.txt

git status

输出:
On branch master
Your branch is up to date with 'origin/master'.    

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   branch.txt
        deleted:    test.js

将branch.txt移动到testDoc目录下

git mv branch.txt testDoc/branch.txt

git status

输出:
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    branch.txt
        renamed:    test.js -> testDoc/branch.txt

查看提交历史

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

  • git log - 查看历史提交记录。
  • git blame - 以列表形式查看指定文件的历史修改记录。

git log

在使用 Git 提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,我们可以使用 git log 命令查看。

使用 git log 命令列出历史提交记录如下:

git log

输出:
commit ccddc6af6777d9496e3d577500a6c84e5235c6bc (HEAD -> master, origin/master, origin/HEAD)
Merge: b38bc3f fad3a22
Author: caodingshuan <15639167751@163.com>
Date:   Fri Apr 14 16:01:58 2023 +0800

    Merge branch 'dev'

commit b38bc3f16dc04325c6c7d61b4abb297068ed936d
Author: caodingshuan <15639167751@163.com>
Date:   Fri Apr 14 10:35:25 2023 +0800

    'test4.js'

commit c8567255a5790da53d25b44125046be7e94e69be
Author: caodingshuan <15639167751@163.com>
Date:   Fri Apr 14 10:34:50 2023 +0800
...

我们可以用 --oneline 选项来查看历史记录的简洁的版本。

git log --oneline

输出:
ccddc6a (HEAD -> master, origin/master, origin/HEAD) Merge branch 'dev'
b38bc3f 'test4.js'
c856725 'test3.js'
bed069d 'test2.js'
3164e22 'test1.js'
ac43a8f '123'
fad3a22 (origin/dev, dev) change
8c17f68 (origin/sit, sit) change
b7846a7 test
9b6ac7b (tag: 1.0.3) update test.js.
5bd63fe add test.js.
9ac5e5d (tag: 1.0.0, origin/feature_1) test

我们还可以用 --graph 选项,查看历史中什么时候出现了分支、合并。以下为相同的命令,开启了拓扑图选项:

git log --graph --oneline

输出:
*   ccddc6a (HEAD -> master, origin/master, origin/HEAD) Merge branch 'dev'
|
| * fad3a22 (origin/dev, dev) change
| * 8c17f68 (origin/sit, sit) change
* | b38bc3f 'test4.js'
* | c856725 'test3.js'
* | bed069d 'test2.js'
* | 3164e22 'test1.js'
* | ac43a8f '123'
|/
* b7846a7 test
* 9b6ac7b (tag: 1.0.3) update test.js.
* 5bd63fe add test.js.
* 9ac5e5d (tag: 1.0.0, origin/feature_1) test

现在我们可以更清楚明了地看到何时工作分叉、又何时归并。

你也可以用 --reverse 参数来逆向显示所有日志。

git log --reverse --oneline

输出:
9ac5e5d (tag: 1.0.0, origin/feature_1) test
5bd63fe add test.js.
9b6ac7b (tag: 1.0.3) update test.js.       
b7846a7 test
8c17f68 (origin/sit, sit) change
fad3a22 (origin/dev, dev) change
ac43a8f '123'
3164e22 'test1.js'
bed069d 'test2.js'
c856725 'test3.js'
b38bc3f 'test4.js'
ccddc6a (HEAD -> master, origin/master, origin/HEAD) Merge branch 'dev'

如果只想查找指定用户的提交日志可以使用命令:git log --author

git log --author=caodingshuan --oneline -5

输出:
ccddc6a (HEAD -> master, origin/master, origin/HEAD) Merge branch 'dev'
b38bc3f 'test4.js'
c856725 'test3.js'
bed069d 'test2.js'
3164e22 'test1.js'

如果你要指定日期,可以执行几个选项:--since--before,但是你也可以用 --until--after

例如,如果我要看 Git 项目中三周前且在四月十八日之后的所有提交,我可以执行这个(我还用了 --no-merges 选项以隐藏合并提交):

git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges

git blame

git blame 命令显示指定文件文件内容每一行最后一次修改记录,

git blame <file>

如下实例:

git blame test.js

输出:
4d5200c8 (caodingshuan 2023-04-14 16:52:02 +0800 1) export default {
4d5200c8 (caodingshuan 2023-04-14 16:52:02 +0800 2)   main: 'index.js',
4d5200c8 (caodingshuan 2023-04-14 16:52:02 +0800 3)   type: 'test',
4d5200c8 (caodingshuan 2023-04-14 16:52:02 +0800 4)   author: 'caodingshuan'
4d5200c8 (caodingshuan 2023-04-14 16:52:02 +0800 5) }

远程操作

git fetch && git merge

git fetch命令将某个远程主机的更新,全部取回本地,通常用来查看其他人的进程,因为它取回的代码对你本地的开发代码没有影响。抓取结果是直接送到本地版本库(Repository)。该命令执行完后需要执行 git merge 将拉取到的代码合并到你所在的任意分支。

  • git fetch <远程主机名> <分支名>:默认情况下,git fetch取回所有分支(branch)的更新。如果只想取回特定分支的更新,可以指定分支名。比如,取回origin主机的master分支:git fetch origin master
  • git merge <远程主机名>/<分支名>:将更新合并到你的当前分支。所取回的更新,在本地主机上要用"远程主机名/分支名"的形式读取。比如origin主机的master,就要用origin/master读取。

接下来我们在远程项目上点击 test.js 并在线修改它。

git fetch origin

输出:
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 1.01 KiB | 6.00 KiB/s, done.
From https://gitee.com/caodingshuan/testproject
   4d5200c..35f3cd0  master     -> origin/master

当远程主机名只有origin,则直接执行git fetch

接着执行

git merge origin/master


输出:
Updating 4d5200c..35f3cd0
Fast-forward
 test.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

当远程更新代码分支与当前分支名称对应一致时,则可直接git merge。如远程更新代码分支为origin/master,本地分支为master。

查看test.js文件,内容已经更改。

此外,也可以使用git rebase 主机名/分支名命令,在本地分支上合并远程分支。

git rebase origin/master

上面命令表示在当前分支上,合并origin/master。

git pull

git pull 命令用于从远程获取代码并合并本地的版本。git pull 其实就是 git fetchgit merge FETCH_HEAD 的简写。

命令格式:git pull <远程主机名> <远程分支名>:<本地分支名>

将远程主机 origin 的 master 分支拉取过来,与本地的 dev 分支合并。

git pull origin master:dev

如果远程分支是与当前分支合并,则冒号后面的部分可以省略。

git pull origin master

在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动"追踪"origin/master分支。

Git也允许手动建立追踪关系。

git branch --track master origin/next
或
git branch --set-upstream-to master origin/next

上面命令指定master分支追踪origin/next分支。

如果当前分支与远程分支存在追踪关系,git pull就可以省略远程分支名。

git pull origin

上面命令表示,本地的当前分支自动与对应的origin主机"追踪分支"(remote-tracking branch)进行合并。

如果当前分支只有一个追踪分支,连远程主机名都可以省略。

git pull

上面命令表示,当前分支自动与唯一一个追踪分支进行合并。

如果合并需要采用rebase模式,可以使用--rebase选项,默认为merge模式,即会保留合并分支的提交记录,而rebase模式则不会。

git pull --rebase <远程主机名> <远程分支名>:<本地分支名>

如果远程主机删除了某个分支,默认情况下,git pull 不会在拉取远程分支的时候,删除对应的本地分支。这是为了防止,由于其他人操作了远程主机,导致git pull不知不觉删除了本地分支。

但是,你可以改变这个行为,加上参数 -p 则会在本地删除远程已经删除的分支。

注:此处删除的是本地仓库记录的远程仓库分支信息,并不会删除之前从远程仓库检出到本地的同名分支,检出的分支还需要手动删除。

git pull -p

# 等同于下面的命令

git fetch --prune origin 
git fetch -p

git push

git push 命令用于从将本地的分支改动上传到远程并合并。

命令格式如下:git push <远程主机名> <本地分支名>:<远程分支名>,如git push origin master:master

注意,分支推送顺序的写法是<来源地>:<目的地>,所以git pull是<远程分支>:<本地分支>,而git push是<本地分支>:<远程分支>。

git push <远程主机名> <本地分支名>:如git push origin master,省略远程分支名,则表示将本地分支推送与之存在"追踪关系"的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。

如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。直接git push origin

如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git push

git push -u origin master

上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,并将本地master分支与远程master分支建立追踪关系,后面就可以不加任何参数使用git push了。

不带任何参数的git push,默认只推送当前分支,这叫做simple方式。此外,还有一种matching方式,会推送所有有对应的远程分支的本地分支。Git 2.0版本之前,默认采用matching方法,现在改为默认采用simple方式。如果要修改这个设置,可以采用git config命令。

git config --global push.default matching
# 或者
git config --global push.default simple

还有一种情况,就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要使用--all选项。

git push --all origin

上面命令表示,将所有本地分支都推送到origin主机。

如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用--force选项。

git push --force origin 

上面命令使用--force选项,结果导致远程主机上更新的版本被覆盖。除非你很确定要这样做,否则应该尽量避免使用--force选项。

最后,git push不会推送标签(tag),除非使用--tags选项。

git push origin --tags

Git 分支管理

几乎每一种版本控制系统都以某种形式支持分支,一个分支代表一条独立的开发线。

分支是用来将特性开发绝缘开来的。在你创建仓库的时候,master 是“默认的”分支。在其他分支上进行开发,完成后再将它们合并到主分支上。

Git 分支实际上是指向更改快照的指针。有人把 Git 的分支模型称为必杀技特性,而正是因为它,将 Git 从版本控制系统家族里区分出来。

创建分支

创建分支命令:git branch branchname

先创建dev分支,并查看所有分支

git branch dev

git branch -a

输出:
  dev
* master
  sit
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/sit

切换到dev,推送到远程,并查看所有分支

git checkout dev

输出:Switched to branch 'dev'

git push --set-upstream origin dev

输出:
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
remote: Create a pull request for 'dev' on Gitee by visiting:
remote:     https://gitee.com/caodingshuan/testproject/pull/new/caodingshuan:dev...caodingshuan:master
To https://gitee.com/caodingshuan/testproject.git
 * [new branch]      dev -> dev
branch 'dev' set up to track 'origin/dev'.

git branch -a

输出;
* dev
  master
  sit
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev
  remotes/origin/master
  remotes/origin/sit

列出分支

列出分支基本命令:git branch。没有参数时会列出你在本地的分支。

git branch

输出:
  dev
* master
  sit

此例的意思就是,我们有一个叫做 master 的分支,并且该分支是当前分支。当你执行 git init 的时候,默认情况下 Git 就会为你创建 master 分支。

切换分支命令:git checkout branchname。当你切换分支的时候,Git 会用该分支的最后提交的快照替换你的工作目录的内容,所以多个分支不需要多个目录。

git fetch取回远程主机的更新以后,可以在它的基础上,使用git checkout -b newBranch 主机名/分支名命令来创建新分支并立即切换到该分支下,从而在该分支中操作。

git checkout -b newBranch origin/master

上面命令表示,在最新origin/master的基础上,创建一个新分支。

当在当前分支基础上创建新分支,则可以省略"主机名/分支"

git checkout -b newtest

输出;Switched to a new branch 'newtest'

git branch

输出:
  dev
  master
* newtest
  sit

使用分支将工作区文件的修改区分开来,从而让我们能够在不同开发环境中做事,并来回切换。

git branch命令的-r选项,可以用来查看远程分支,-a选项查看所有分支。

git branch -r
git branch -a

删除分支

删除分支命令:git branch -d branchname

删除newtest分支,并查看结果

git branch -d newtest

输出:Deleted branch newtest (was 2e3ef73).

git branch

输出:
* dev
  master
  sit

分支合并

一旦某分支有了独立内容,你终究会希望将它合并回到你的主分支。 你可以使用git merge命令将任何分支合并到当前分支中去:

将dev分支合并到master分支,并删除dev分支

git merge dev

输出;
Updating 2e3ef73..f571eb1
Fast-forward
 test.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

git branch -d dev

输出:Deleted branch dev (was f571eb1).

git branch

输出:
* master
  sit

合并冲突

合并并不仅仅是简单的文件添加、移除的操作,Git 也会合并修改。

创建dev分支,修改test.js文件,并提交

git checkout -b dev

输出:Switched to a new branch 'dev'

// 修改test.js文件后

git diff

输出:
diff --git a/test.js b/test.js
index 1cd940e..1a8cb18 100644 
--- a/test.js
+++ b/test.js
@@ -1,5 +1,5 @@
 export default {
-  main: 'index.js devchanged',
-  type: 'test devchanged',
-  author: 'caodingshuan devchanged'
+  main: 'index.js devEdit',
+  type: 'test devEdit',
+  author: 'caodingshuan devEdit'
 }

git commit -am "dev修改" 
[dev 719f50d] dev修改
 1 file changed, 3 insertions(+), 3 deletions(-)

切换到master分支,修改test.js文件,并提交

git checkout master

输出:
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

// 修改完test.js文件
git diff

输出:
diff --git a/test.js b/test.js
index c833ee3..aaeb8d4 100644 
--- a/test.js
+++ b/test.js
@@ -1,5 +1,5 @@
 export default {
-  main: 'index.js dev',
-  type: 'test dev',
-  author: 'caodingshuan dev'
+  main: 'index.js masterEdit',
+  type: 'test masterEdit',
+  author: 'caodingshuan masterEdit'
 }

git commit -am "master提交" 

输出:
[master 3ae6877] master提交
 1 file changed, 3 insertions(+), 3 deletions(-)

git push

输出:
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 348 bytes | 348.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/caodingshuan/testproject.git
   2e3ef73..3ae6877  master -> master

切换到master分支,并将dev合并到master,则出现冲突

git merge dev

输出:
Auto-merging test.js
CONFLICT (content): Merge conflict in test.js
Automatic merge failed; fix conflicts and then commit the result.

git diff

输出:
diff --cc test.js
index aaeb8d4,1a8cb18..0000000
--- a/test.js
+++ b/test.js
@@@ -1,5 -1,5 +1,11 @@@       
  export default {
++<<<<<<< HEAD
 +  main: 'index.js masterEdit',
 +  type: 'test masterEdit',
 +  author: 'caodingshuan masterEdit'
++=======
+   main: 'index.js devEdit',
+   type: 'test devEdit',
+   author: 'caodingshuan devEdit'
++>>>>>>> dev
  }
``

手动修改冲突后,添加到暂存区,后进行提交

```cmd
git diff

输出:
diff --git a/test.js b/test.js
index aaeb8d4..1a8cb18 100644 
--- a/test.js
+++ b/test.js
@@ -1,5 +1,5 @@
 export default {
-  main: 'index.js masterEdit',
-  type: 'test masterEdit',
-  author: 'caodingshuan masterEdit'
+  main: 'index.js devEdit',
+  type: 'test devEdit',
+  author: 'caodingshuan devEdit'
 }

git add .

git commit -m "冲突解决" 

输出:
[master d6d1c68] 冲突解决
 1 file changed, 3 insertions(+), 3 deletions(-)

git push

Git 标签

创建标签

  • git tag <tagname>:给最新一次(HEAD)提交打上tagname的标签。
  • git tag -a <tagname>:给最新一次(HEAD)提交打上(打开你的编辑器)带注解的tagname的标签。会记录这标签是什么时候打的,谁打的。
  • git tag -a <tagname> -m "注解":指定标签信息命令,不会打开编辑器。

当我们执行 git log --decorate 时,我们可以看到我们的标签了。

git tag v1.0

git tag -a v1.1

输出:hint: Waiting for your editor to close the file... unix2dos: converting file D:/project/personal/testproject/.git/TAG_EDITMSG to DOS format...
dos2unix: converting file D:/project/personal/testproject/.git/TAG_EDITMSG to Unix format...

git log --decorate --oneline  --graph

输出:
* d6d1c68 (HEAD -> master, tag: v1.1, tag: v1.0, origin/master, origin/HEAD) 冲突解决
* 3ae6877 master提交
* f571eb1 (origin/dev) dev提交
* 2e3ef73 'addTest'
* eafeb09 '123'
* 03e3adf 'test2'
* 7d71042 'test'
* 5fa3a21 update test.js.
* 4d5200c 'test.js'
* 52162e9 'testchanged3'
* e7176ba 'testchanged2'
* 4e5ea32 'testchanged1'
*   ccddc6a Merge branch 'dev'
|
| * fad3a22 change
| * 8c17f68 (origin/sit, sit) change
* | b38bc3f 'test4.js'
* | c856725 'test3.js'
* | bed069d 'test2.js'
* | 3164e22 'test1.js'
* | ac43a8f '123'
|/
* b7846a7 test
* 9b6ac7b update test.js.
* 5bd63fe add test.js.
* 9ac5e5d test

如果我们忘了给某个提交打标签,又将它发布了,我们可以给它追加标签。

git tag -a v0.9 2e3ef73
git log --decorate --oneline --graph

输出:
* d6d1c68 (HEAD -> master, tag: v1.1, tag: v1.0, origin/master, origin/HEAD) 冲突解决
* 3ae6877 master提交
* f571eb1 (origin/dev) dev提交
* 2e3ef73 (tag: v0.9) 'addTest'
* eafeb09 '123'
* 03e3adf 'test2'
* 7d71042 'test'
* 5fa3a21 update test.js.
* 4d5200c 'test.js'
* 52162e9 'testchanged3'
* e7176ba 'testchanged2'
* 4e5ea32 'testchanged1'
*   ccddc6a Merge branch 'dev'
|
| * fad3a22 change
| * 8c17f68 (origin/sit, sit) change
* | b38bc3f 'test4.js'
* | c856725 'test3.js'
* | bed069d 'test2.js'
* | 3164e22 'test1.js'
* | ac43a8f '123'
|/
* b7846a7 test
* 9b6ac7b update test.js.
* 5bd63fe add test.js.
* 9ac5e5d test

git tag:查看所有标签

git tag

输出:

v0.9
v1.0
v1.1

删除标签

删除本地标签

git tag --delete tagname:删除本地指定标签

git tag 

输出:
v0.9
v1.0
v1.1

git tag --delete v0.9

输出:Deleted tag 'v0.9' (was ea32475)

git tag

输出:
v1.0
v1.1

git tag -l | xargs git tag -d:批量删除本地所有标签,在git bash命令行工具执行。

删除远程标签

先将本地标签上传到远程,执行git push --tag

git push --tags

输出:
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 156 bytes | 156.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0        
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/caodingshuan/testproject.git
 * [new tag]         v1.0 -> v1.0
 * [new tag]         v1.1 -> v1.1

git ls-remote --tags origin:列出远程存储库上标签

git ls-remote --tags origin

输出:
d6d1c682bbd645bba5b61e22b87b9bb5716b8f35        refs/tags/v1.0   
a44f20639b6fdf6a42d01d07f96362ed91e060f2        refs/tags/v1.1   
d6d1c682bbd645bba5b61e22b87b9bb5716b8f35        refs/tags/v1.1^{}

git push origin --delete tagName:删除远程指定标签

git push origin :tagname: 将"空"引用推送到远程指定标签,进行远程标签删除

git push origin --delete tagName1 tagNam2 tagNam3:手动批量删除远程多个标签

git push origin --delete v1.0 或 git push origin :v1.0

输出:
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/caodingshuan/testproject.git
 - [deleted]         v1.0

git ls-remote --tags origin

输出:
a44f20639b6fdf6a42d01d07f96362ed91e060f2        refs/tags/v1.1
d6d1c682bbd645bba5b61e22b87b9bb5716b8f35        refs/tags/v1.1^{}

git show-ref --tag | awk '{print ":" $2}' | xargs git push origin:批量删除所有远程标签,在git bash命令行工具执行。

注意:

  • 删除tag,本地与远程是分开操作的。如果想把本地以及远程的tag全部删除,两个批量删除命令分开执行即可。
  • 否则本地删除,远程没有删除,则在pull拉取后,远程标签会同步到本地。本地没有删除,远程删除,则push --tag时,会将本地标签同步到远程。

SSH配置

如果你本地和远程Git仓库之间的传输是通过SSH加密的,那我们需要配置验证信息。

使用SSH公钥可以让你在你的电脑和 Gitee 通讯的时候使用安全连接(Git的Remote要使用SSH地址)

使用ssh-keygen -t rsa -C "youremail"命令生成 SSH Key。

后面的 your_email 改为你在Git仓库上注册的邮箱,之后会要求确认路径和输入密码,我们这使用默认的一路回车就行。

成功的话会在用户目录下生成 .ssh 文件夹,进去,打开 id_rsa.pub,复制里面的内容。

ssh-keygen -t rsa -C "15639167751@163.com" 

输出:
Generating public/private rsa key pair.
Enter file in which to save the key (C:Userscaodingshuan/.ssh/id_rsa):  ## 直接回车
Enter passphrase (empty for no passphrase): ## 直接回车
Enter same passphrase again: ## 直接回车
Your identification has been saved in C:Userscaodingshuan/.ssh/id_rsa.
Your public key has been saved in C:Userscaodingshuan/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:QW48fxlTUSw72uaSFDucWoUlbe3XCv6GKunD9ahXtK0 15639167751@163.com
The key's randomart image is:
+---[RSA 3072]----+
|        .    .o=.|
|       +    ..= o|
|        *   o= +.|
|       . +  =++ +|
|        S .+o@ o.|
|          ..% =  |
|       . o B O   |
|        = + E +  |
|       .o=.. o   |
+----[SHA256]-----+

回到 git 上,进入账户设置,进入SSH公钥菜单栏,将本地id_rsa.pub文件内容粘贴到公钥输入区,标题填写当前公钥对应邮箱,方便后续成员变动进行处理。

为了验证是否成功,需要进行git地址验证:

ssh -T git@gitee.com

输出:
Warning: Permanently added the ED25519 host key for IP address '212.64.63.215' to the list of known hosts.
Hi 曹定栓! You've successfully authenticated, but GITEE.COM does not provide shell access.

以上表明已经配置成。

之前一直是通过https进行代码仓库的下载,现在使用ssh进行下载。这边第一次执行会报错,重新执行就OK了。

git clone git@gitee.com:caodingshuan/testproject.git 

下载完成,进行目录,执行git remote -v,可以看到remote地址为SSH地址

git remote -v

输出:
origin  git@gitee.com:caodingshuan/sshdemo.git (fetch)
origin  git@gitee.com:caodingshuan/sshdemo.git (push) 

当在单独项目上添加公钥时(如果所在git管理工具有此功能的话),此时权限会受到限定:

部署公钥允许以只读的方式访问仓库,主要用于仓库在生产服务器的部署上,免去HTTP方式每次操作都要输入密码和普通SSH方式担心不小心修改仓库代码的麻烦。

部署公钥配置后的机器,只支持clone与pull等只读操作。如果您想要对仓库进行写操作,请 添加个人公钥

常规项目设置

  • git不忽略文件名大小写:git config core.ignorecase false,默认为true,需要在项目根目录进行使用。

工具型命令

  • 退出git命令行: 按 q
  • 使用内建的图形化git命令行:gitk
  • 显示历史记录时,每个提交的信息只显示一行:git config format.pretty oneline
  • 交互式添加文件到暂存区:git add -i
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。