Git 简单介绍

文章目录

  • 一、Git 安装
  • 二、工作流程
  • 三、基本概念
  • 四、常用操作
    • git init
    • git config
    • git status
    • git log
    • 常用命令:
      • git add
      • git commit
      • git clone
      • git rm
      • git mv
      • git branch
      • git checkout
      • git merge
      • git push
      • git pull
  • 五、其他
    • pull - request 含义:

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

一、Git 安装

      windows安装:进入网站 https://git-scm.com/ 安装,ubuntu配置:apt install git。当前于 Win 下已安装 Git 版本 2.40.1。

二、工作流程

      一般工作流程如下:

  • 克隆 Git 资源作为工作目录。
  • 在克隆的资源上添加或修改文件。
  • 如果此时其他人修改了,可以更新资源。
  • 在提交前查看修改。
  • 提交修改。
  • 在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。
    Git 简单介绍_第1张图片

三、基本概念

  • 工作区: 就是你在电脑里能看到的目录,即平时存放项目代码的地方。
  • 暂存区: 英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。用于临时存放你的改动,事实上它只是一个文件,保存即将提交的文件列表信息。
  • Git 仓库: Git 仓库位于工作区中的 .git 中。这里边有提交的所有版本数据。其中,HEAD 指向最新放入仓库的版本。

      通常我们执行的操作为:1. 在工作目录中添加、修改文件;2. 将需要进行版本管理的文件放入暂存区域;3. 将暂存区域的文件提交到 Git 仓库。相对应的,Git 管理的文件有三种状态:已修改(modified)、已暂存(staged)和已提交(committed)。

      下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

Git 简单介绍_第2张图片

      图中的 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 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

四、常用操作

git init

      Git 使用 git init 命令来初始化一个 Git 仓库,在执行完成 git init 命令后,Git 仓库会生成一个 .git 目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。

      直接使用。

      git init newrepo 会在 newrepo 目录下出现 .git 目录。

git config

      用来进行 git 的设置,显示当前的 git 配置信息:git config --listgit config --global --list。来带有参数 --global 表示针对所有仓库有效。

      设置提交代码时的用户信息:

$ git config --global user.name "abc"
$ git config --global user.email "[email protected]"

git status

      可以查看在自上次提交之后是否有对文件进行再次修改。

git log

      用于查看 Git 仓库中提交历史记录。它显示了从最新提交到最早提交的所有提交信息,包括提交的哈希值、作者、提交日期和提交消息等。


常用命令:

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

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

git add

      添加文件/目录到暂存区。git add ...或者git add

      其中在 git2中, git add . 等同于 git add -A:表示会监控工作区的状态树,它会把工作区的所有变化提交到暂存区,包括修改(modified)、新文件(Untracked files)、删除的文件(deleted)。 但使用 .在 git1.x 中`不会监控删除的文件。

      在 git 提交时碰到如下警告:

$ git add hello.cpp
warning: in the working copy of 'hello.cpp', LF will be replaced by CRLF the next time Git touches it
$ git config --global core.autocrlf true

      是因为换行符在不同平台上的表示不同。

  • CR(CarriageReturn回车 ‘\r’ ):回到一行的开头,ASCII代码是13
  • LF(LineFeed换行 '\n’):另起一行,ASCII代码是10

      应用情况:

  • DosWindows平台: 使用回车(CR)和换行(LF)两个字符来结束一行,回车+换行(CR+LF),即“\r\n”;所以我们平时编写文件的回车符应该确切来说叫做回车换行符。
  • MacLinux平台:只使用换行(LF)一个字符来结束一行,即“\n”;

      影响:

  1. 一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;
  2. 而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。
  3. Linux保存的文件在windows上用记事本看的话会出现黑点。

      在 Windows 下,通过设置 core.autocrlf=true ,Git 可以在你提交时自动地把回车(CR)和换行(LF)转换成换行(LF),而在检出代码时把换行(LF)转换成回车(CR)和换行(LF)。

$ git config --global core.autocrlf true

git commit

      提交暂存区的指定文件到本地仓库。git commit file1,file2..-m [message],其中 file1,file2是可选的,如果为空时,表示提交整个暂存区到本地仓库;message 可以是一些备注信息,在 Linux 下使用单引号 ',在 win 下使用双引号"

      在 commit 提交时,会显示出提交者的信息,名称和邮箱。这两个信息 git 会自动生成,如果需要显示修改的话,采用 git config --global user.name "Your Name" 和 git config --global user.email [email protected]

      如果觉得 git add 提交缓存的流程太过繁琐,Git 也允许用 -a 选项跳过这一步,等同于先执行 git add . 再执行 git commit -m “message”。如下

$ git commit -am "message"

git clone

      其用法为:git clone repo: 远程仓库,或者是本地目录。directory: 目标目录名称。directory 为可选项,为空的话默认在当前目录拷贝一份远程仓库的完整内容。

      在远程连接时,一般可以通过 https 和 ssh 来拉取代码,采用 https 时: git clone https克隆地址,需要在弹出的对话框中输入远程仓库的用户名和密码;使用 ssh 时则需要配置 ssh 公钥,公钥添加进远程仓库,私钥用来识别当前操作的用户身份。

      ssh 密钥生成可参考:先在 Bash 中生成密钥对,然后将公钥添加到 Gitee 账户中即可,第一次远程连接时,会有提示,只需要输入yes即可,如下:

$ git clone [email protected]:cedirczou/mini-pm.git
Cloning into 'mini-pm'...
The authenticity of host 'gitee.com (180.76.198.77)' can't be established.
ED25519 key fingerprint is SHA256:+ULzij2u99B9eWYFTw1Q4ErYG/aepHLbu96PAUCoV88.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'gitee.com' (ED25519) to the list of known hosts.
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (6/6), done.

git rm

      用来删除文件。

      git rm file :将文件从暂存区和工作区中删除 -f 表示强制删除。

      git rm -cached file:将文件从暂存区域移除,但仍保留在当前工作区中。

git mv

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


      Git 分支

      在版本控制过程中,同时推进多个任务,我们就可以创建每个任务单独的分支。使用分支意味着可以把自己的工作从开发主线上分离开,开发自己分支的时候,不会影响主线分支的运行。分支可以简单的理解为副本,一个分支就是一个单独的副本(分支底层其实也是指针的引用)

      在 master 这个主线上运行,运行的同时要增加功能,那我们就可以把master复制一份出来,在复制的地方进行开发,开发完之后在对 master 进行合并更新;当我们引入的新功能有 bug 时,就可以从 master 分支再引一个分支 hot-fix (热修复分支),对代码进行修改,修改后再合并到 master 。

      下图是常见的 Git 分支模型:

Git 简单介绍_第3张图片

  • master【主分支】:为稳定的版本分支,每一个节点的代码均为可发布的。
  • dev【开发分支】:主要用于开发,其包含多名工程师提交的代码。
  • features【功能分支】:每一个工程师在开发新功能时以 dev 分支为基础创建的分支。
  • release【预发布分支】:一般用于功能开发完毕,所有工程师的代码进行最后的测试与bug修复的分支。
  • hotfix【热修复分支】:一般用于紧急修复现网运行程序的 bug。

git branch

       git branch:不带参数时,git branch 会列出你在本地的分支。 前面带有 * 的是当前分支;git branch -a 会列出全部分支(本地和远程)。当执行 git init 的时候,默认情况下 Git 就会为你创建 master 分支。

      git branch branchname:创建一个名为 brachname 的分支。

      git branch -d branchname:删除分支 brachname。

git checkout

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

      git checkout -b branchname:创建一个新分支并立即切换到该分支下。

      不同分支之间的内容相互独立,这仅限于在 commit 之后,在这之前,不管在哪个分支创建的文件,所有分支都能看到该文件,而这个文件归属于谁呢?归属于第一个执行 add 和 commit 的分支。

$ ls
README.en.md  README.md
$ git branch
* master
$ git checkout -b dev
Switched to a new branch 'dev'
$ ls
README.en.md  README.md
$ echo "hello,dev." > dev.txt
$ ls
README.en.md  README.md  dev.txt

$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ ls
README.en.md  README.md  dev.txt
$ git checkout dev
Switched to branch 'dev'

$ ls
README.en.md  README.md  dev.txt

$ git add dev.txt
$ git commit -m "new dev"
    ...
 1 file changed, 1 insertion(+)
 create mode 100644 dev.txt

$ ls
README.en.md  README.md  dev.txt
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ ls
README.en.md  README.md

--------------------------------------------------------------------


$ git checkout dev
Switched to branch 'dev'
$ vim abc.c
$ ls
README.en.md  README.md  abc.c  dev.txt

$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ ls
README.en.md  README.md  abc.c

$ git add abc.c
$ git commit -m "new abc"
    ...
 1 file changed, 5 insertions(+)
 create mode 100644 abc.c
$ ls
README.en.md  README.md  abc.c

$ git checkout dev
Switched to branch 'dev'
$ ls
README.en.md  README.md  dev.txt

git merge

      git merge:合并分支。可将任何分支合并到当前分支中去,它只会影响当前分支,不会影响其他分支。默认采用 fast-forward 策略。它有一些常用的参数如:

      git merge --no-commit maint·

      将分支maint合并到当前分支中,但不要自动进行新的提交。

       git merge -s ours obsolete

      合并obsolete分支到当前分支,使用ours合并策略。

      git merge fixes enhancements

      合并分支fixesenhancements在当前分支的顶部,使它们合并。

      git merge dev

      将分支dev合并到当前分支中,自动进行新的提交。

      Git 在合并分支时,会分别将两个分支的 commit 记录(每一次 commit 提交时所做的操作),相对于当前需要合并的两个分支最近一次相同版本记录 base 进行比较。如果:

  1. 分支 master 相比 base 有变化,另一个分支 dev 相比 base 无变化,那么:
  • 如果在 master 下进行:

    git merge dev
    

    会提示 Already up to date.,即 master 不会发生变化。

  • 如果在 dev 下进行:

    git merge master
    

    那么会将在 master 最近提交过程中所做的更改全部实施在 dev 分支上,最终在 dev 上看到的即是 master 的全部内容。

  1. 如果 master 和 dev 相比较 base 都有变化。那么:
  • 如果将 dev 合并到 master 上面:

    git merge dev
    

    git 会以当前 master 分支项目代码为基础,然后将当前的 dev 项目代码和 base 做比较,将 dev 在 base 上的操作在 master 上在执行一遍。

  • 将 master 合并到 dev 上的操作同上。


      解决冲突示例:

$ git branch
* master

$ ls
README.md  m.txt


$ git checkout -b dev
Switched to a new branch 'dev'

$ vim m.txt
$ cat m.txt
devdev

$ git add .
warning: in the working copy of 'm.txt', LF will be replaced by CRLF the next time Git touches it

$ git commit -m "dev modify"
[dev 5630f6b] dev modify

 1 file changed, 1 insertion(+), 1 deletion(-)

$ ls
README.md  m.txt


$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 27 commits.
  (use "git push" to publish your local commits)

$ ls
README.md  m.txt
vim m.t

$ vim m.txt
$ cat m.txt
mastermaster

$ git add .

$ git commit -m "master modify"
[master b0d554b] master modify

 1 file changed, 1 insertion(+), 1 deletion(-)

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

$ git diff
diff --cc m.txt
index 311d061,1291d09..0000000
--- a/m.txt
+++ b/m.txt
@@@ -1,1 -1,1 +1,5 @@@
++<<<<<<< HEAD
 +mastermaster
++=======
+ devdev
++>>>>>>> dev

$ vim m.txt
$ cat m.txt
mastermaster

$ git add .

$ git commit -m "done"
[master e9fcf9f] done

$ git merge dev
Already up to date.

      master 和 dev 分支相对于原来的 txt 都进行了修改,在 m.txt 中能够看到它们的修改变化,此时需要我们手动进行修改,选择保留哪一个分支的结果。在本例中保留 master 分支所做的修改,m.txt 中的内容改为 mastermaster,在重新进行 add commit 操作来提交我们所做的修改。

git push

      作用是将本地当前分支的代码合并到远程指定的分支上。命令格式为:git push <远程主机名> <本地分支名>:<远程分支名>

      如果本地分支名与远程分支名相同,则可以省略冒号:git push <远程主机名> <本地分支名>。如果本地版本与远程版本有差异,但又要强制推送可以使用 --force 参数:git push --force origin master 本地仓库可以和多个远程主机建立联系,如果没有特殊制定,就只有一个,名字默认为 origin。

  1. 如果我们已经从一个远程主机上克隆了项目,在修改之后选择 push 的时候,可以忽略后面的远程主机名。如下:
$ git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 393 bytes | 393.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
...
  1. 如果是在本地新建的项目,通过 init,add,commit,到 push 的时候,不能简单的采用 git push 了,如下:
$ git push
fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

git remote add <name> <url>

and then push using the remote name

git push <name>

      此时需要采用 git remote 来配置远程主机信息,其常用命令如下:

      git remote -v:列出当前仓库中已配置的远程仓库,并显示它们的 URL。

      git remote add :添加一个新的远程仓库。指定一个远程仓库的名称和 URL,将其添加到当前仓库中。 其中url 可以采用 https 或者 ssh。

      git remote rm :从当前仓库中删除指定的远程仓库。

      通过 git remote add origin ssh_url 添加远程仓库之后,执行 git push -f origin master即可强制合并到远程仓库(用当前目录中的文件替换远程仓库)。

      通常在远程主机新建仓库之后,先 clone 下来,然后在这个目录中对文件进行增加,删除和修改,然后在 add ----> commit,最后直接 git push 即可

git pull

      用于从远程主机获取分支代码且合并到本地的版本。它等同于 git fetch 和 git merge FETCH_HEAD 的简写。其中 git fetch 的作用是拉取远程主机的分支项目代码到本地。

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

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

git pull origin master:brantest

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

git pull origin master

五、其他

pull - request 含义:

      pull - request 的含义指的是请求别人拉取自己修改后的代码。 具体可见:https://blog.csdn.net/wan212000/article/details/127387895

你可能感兴趣的:(C/CPP,git)