linux---git

什么是git

分布式版本控制系统(Distributed Version Control System,简称 DVCS)
本质:git就是一套用于管理文件/目录不同时刻状态的软件
Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改 推送 给对方,就可以互相看到对方的修改了。

什么是分布式系统

分布的对象:计算机

系统:肯定是通过某种方式连接起来形参的系统

分布式系统:

就是计算机之间通过网络连接起来,协同工作而形参的系统就是分布式系统

git就是用来控制这些分布式系统的系统,所以叫:分布式版本控制系统

用git来干什么---(文件)版本控制

用来保存文件或者目录不同时刻的版本(被修改),以便方便恢复之前的文件

安装git:

sudo apt-get install git

用户信息

当安装完 Git 应该做的 第一件事 就是设置你的用户名称与邮件地址。这样做很重要,因为每一个 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中, 不可更改
$ git config --global user.name "你远程仓库的用户名"                //
$ git config --global user.email "你远程仓库配置时用的邮箱"
注意:不要把用户名填写为直接linux的用户名
如果你没有进行用户信息的配置,当你提交时,报错:

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

 

补充:(1.1) 全局变量
 --global  表示全局的,即用户的配置和邮箱的配置在当前用户都有效,该配置会出现在 ~/.gitconfig 文件中,~表示当前用户的目录。

    (1.2)局部变量
既然有全局的,那么肯定有局部的啊!局部的是不加 --global 的,如下:

git config  user.name  "username"  
git config  user.email  "email"

局部是配置的用户名和邮箱只对当前仓库起效的,它的配置信息会在当前仓库根目录/.git/config文件下。

ssh和http都需要。

检查配置信息

如果想要检查你的配置,可以使用 git config --list 命令来列出所有 Git 当时能找到的配置

用命令修改
这里演示修改
本地仓库的用户名和邮箱:

git config --replace-all user.name "name"

git config --replace-all user.email "123@qq.com"

ssh生成和配置:

ssh的作用

就是文件传输时使用的协议,你也可以选择https协议,而不需要设置ssh密钥。但是每一次使用https都要输入账号和密码,而ssh协议设置好密钥之后,进行提交,获取的时候就不需要输入账户和密码了。

生成:

1,ssh-keygen -t rsa -C "你自己远程仓库的邮箱"

2,三个回车

三次回车之后会告诉你,生成的存放密钥的文件在哪:

Your identification has been saved in /home/wujingyou/.ssh/id_rsa
Your public key has been saved in /home/wujingyou/.ssh/id_rsa.pub

4,打开id_rsa.pub,复制里面所有字符,用来配置远程仓库

配置

setting-->SSH and GPG keys--->new ssh key

随便填title,粘贴复制的密钥到key,add ssh key

一个系统上只需要创建一个ssh就可以了。

git能够进行文件传输的条件

1,远程仓库名和邮箱的配置。

2,git remote 获取远程仓库。

3,同步本地仓库和远程仓库:

1》git pull peername branch

或者 2》git pull --rebase peername branch

4,能够使用ssh协议的前提一定是在远程仓库添加本地仓库的密钥。

5,如果使用你的git利用SSH去操作任何一个远程仓库,那么操作之前一定要先在远程仓库添加你的git的密钥,让你的密钥有权限。

远程仓库http和ssh协议的切换

查看git参数配置

git config --list

现在是ssh.

配置为http

git config <--global> remote.origin.url "http的url"

基本的 Git 工作流程如下:

1. 在工作目录中修改文件。
2. 暂存文件,将文件的快照放入暂存区域。
3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。

创建版本库(仓库--repository)-- .git---git init


创建一个工作目录,进入工作目录(工作区),执行命令git init在当前工作目录下创建一个本地仓库.git

.git目录

.git是什么

本质上就是一个目录,为什么称为仓库,因为在这个仓库里保存所有我们需要进行版本管理的文件

我们在工作目录进行文件的操作(修改,删除等),然后再将这些文件

放入(add)暂存区,再提交到本地仓库(.git目录),如果有需要,再推送到远程仓库。

为什么git init之后,git branch查看不到任何分支

git init的两个作用

1,创建版本库;

2,创建master分支;

但是此时的本地仓库没有和远程仓库关联起来,所以git branch查看不到任何分支。

所以当我们创建仓库之后,需要git pull远程仓库使本地仓库和远程仓库关联起来。

工作目录

就是我们git init生成.git目录的目录,在这个目录对文件进行操作。就是我们工作的目录。

注意不是.git仓库目录。

输出工作目录(仓库根目录)所在目录路径的命令

git rev-parse --show-toplevel

不进行git init可以git remote吗

不行。在 Git 中,Git 仓库是一个专门的目录,需要通过 `git init` 命令来初始化并创建。通过 `git init` 命令可以将当前目录初始化为一个 Git 仓库,然后才能使用 `git remote` 命令来管理远程仓库的连接和操作。

如果您在一个非 Git 仓库的目录下直接执行 `git remote` 命令,会收到错误提示 "Not a git repository"。这是因为 Git 不知道当前目录是否运行在 Git 仓库中,因为没有初始化过 Git 仓库,因此无法管理远程仓库。

因此,要使用 `git remote` 命令,需要首先在 Git 仓库中执行 `git init` 命令来创建 Git 仓库,并使用 `git remote` 命令来添加和管理远程仓库的连接和操作。

暂存区(index,stage)

什么是暂存区:

暂存区实质上是一个在.git仓库中的index文件

 暂存区存在的意义

为什么需要暂存区,直接从工作目录提交到本地仓库不就好了:

有些朋友感觉暂存区多余,其实并非如此,通过这个过渡性区域可以使提交更加条理,避免无用琐碎提交。

举个比较生活化的例子,需要将一车放置杂乱无章的各类货物有序的放入仓库,最好的办法是将货物先有条理的整理到仓库门口空地上,这个空地相当于暂存区,然后再将货物用叉车运到仓库。还有一个作用就是可以更加方便的对文件进行版本管理,比如版本的回溯

.git内部: 

本地仓库

什么是本地仓库

 查看远程仓库

git remote show origin(远程仓库在本地的链接)

添加远程仓库:

作用(意义):

1,将远程仓库在本地建立一个简单的使用链接标识

2,可以简单的实现本地仓库和远程创库的信息互交

两种方式:

1,使用http协议
git remote add name url(http)

2,使用ssh协议:

git remote add peername url(ssh,code中可见)

peername:是你可以随便给远程仓库取的别名,你可以通过这个别名直接操作,访问远程仓库

clone和添加远程仓库的区别:


1,clone会通过网络访问远程仓库,然后复制(clone)远程仓库的数据和分支到本地仓库,在本地创建一个和远程仓库一样的仓库,添加只是把远程仓库的URL链接在本地做一个标识,以供使用,不通过网络访问远程仓库,也不创建仓库。

2,remote不会创建目录,需要自己创建属于这个仓库的工作目录。

注意:

1,自己创建一个目录用于和新的远程仓库工作时,进入这个目录,因为这个目录是空的,不是clone的,所以只是普通目录,而不是工作目录,因为没有git init初始化为工作目录,所以即使我们fetch或者创建文件或者目录,都没有版本库(.git)来进行管理。这个时候,这个目录以及其中的数据(文件和目录)就会交给上级父目录或者更上级的拥有版本库(.git)的版本库管理。所以,要记得创建工作目录时一定要git init。

查看远程仓库的命令:


git remote 

也可以指定选项 -v ,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。
git remote -v
更详细的命令:
git remote show peername

重命名远程仓库在本地的链接标识:

git remote  rename  oldpeername  newpeername

移除远程仓库在本地的链接标识:

git remote rm peername

从远程仓库获取资源:

添加远程创库之后就可以拉取远程仓库中有但本地仓库没有的信息,可以运行

git fetch peername

这个命令会访问远程仓库,从中拉取所有你还没有的数据。执行完成后,你将会拥有那个远程仓库中所有分支的 引用,可以随时合并或查看。
git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作

 获取git 仓库的两种方法:

1,在现有工作目录下初始化本地仓库:

运行git init 就可以在本工作目录创建. git 仓库以供使用

.git就是本地仓库/版本库, 

工作区:

本地工作目录

暂存区:

本地仓库中的一个叫index或者stage的文件

2,克隆远程仓库:


克隆仓库的命令:
1,git clone url

2,git clone url 本地仓库名

第一种情况克隆所得目录和远程仓库同名


url是要克隆的仓库的网址(可以使用https协议,也可以用ssh协议),https比较麻烦,还要用户名,密码,还要配置还令牌。

 你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写。

使用以上命令时git会默认生成一个指向你clone的远程仓库的标签——origin
可以通过这个标签代替url来获取远程仓库文件和push文件给远程仓库。
如果不在url之后给出clone的仓库的名称,则clone到本地的仓库与远程仓库同名

克隆远程仓库的作用

(这也是获取远程仓库文件,别人的文件的方式)

克隆将获取所有文件。

git clone (http)

网络代理导致的各种git错误

Failed to connect to 127.0.0.1 port 1080: Connection refused

如果是访问github的仓库,可能是因为网络代理(--clash)没有开。

Connection timed out after 12312 milliseconds

如果代理开了,出现这个问题,就是不能上网的意思,检查网络。

以上所有问题只需要关闭代理即可:

1,查看系统网络代理:

env | grep -i proxy  

2,unset 关闭后面四个代理(git的时候指定是哪个代理的端口有问题就关闭哪个):

unset http_proxy https_proxy ALL_PROXY all_proxy

3,重启终端或运行以下命令,使更改生效:

source ~/.bashrc  

4,再次查看网络代理:

env | grep -i proxy  

链接

注意:这个关闭只是临时的,只是在当前终端有效。

正确的关闭代理的方式

只需要关闭掉clash代理文件,之后开启的终端自然不会再有代理。

gnutls_handshake() failed: Error in the pull function.

TLS或者SSL握手问题。

同上:

1,关闭clash代理文件;

2,关闭代理配置。

3,从新打开新的终端。

怎样获取SSH网址

ssh,code中可见

git add

工作目录中的文件不外乎三种状态:已跟踪和未跟踪,未暂存。
已跟踪的文件:git add 成功加入暂存区的文件
未跟踪的文件:没有git add 的新文件

修改已跟踪的文件:被修改之后的文件,在git的记录中就不再在暂存区了,所以需要在此git add 加入。
(凡是用git进行管理的文件,对其进行修改之后,修改之后的文件就是一个新的文件对象,必须要从新加入仓库)
使用git diff /git diff 文件名  可以查看文件被修改的地方,linux中绿色字体是被改变的内容(增加,减少,改动)

如果要向本地仓库添加文件,这个文件必须在这个仓库的工作目录下

向本地仓库添加文件:


看图可知:


第一步:git add 文件名
第二步:git commit 文件名
注意,用git commit 提交文件到仓库时,日志是必须要写的,否则提交不了,就是-m " "。

第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区

第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支

提交之后,暂存区就没有内容了

git add -A  添加所有变化
git add -u  添加被修改(modified)和被删除(deleted)文件,不包括新文件(new)
git add .   添加新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件

刚创建的创库可能git add .会有错误,直接git add 文件名

如何添加空目录

git中add不了空目录,但是我们可以在空目录中设置-----  .gitignore文件。

让空目录不空

如何取消放入暂存区的文件

git reset HEAD 文件名

是如何知道文件添加给哪一个本地仓库:

提交之后系统会告诉你由哪个分支提交到哪一个仓库

对已加入本地仓库的文件进行修改之后:

git commit

每一次commit都会产生一个新的blob提交节点。

修改commit

有时候不想产生新的节点,指向修改上一次提交的日志。

git commit --amend

撤销commit

 git push


刚创建的分支第一次推送需要指定上游:git push -u peername branch

peername可以是ssh生成的,也可以是http生成的

-u的用法,加了参数-u后,以后即可直接用git push代替git push origin master

也可以不加-u---upstream(上游)---设置本地这个当前分支和远程分支的关联关系,以后要推送当前分支到远程的这个分支,就不需要指定了。

注意:很多网上的文章说git push -u origin master是指定本地master分支和远程origin仓库的master分支的对应关系,其实不对,不一定就是本地master,而是当前分支。

链接

1,git push---默认只推送当前分支

2,git push -u origin master

3,git push origin master

链接

不建立分支关系,只传递

只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。当你和其他人在同一时间
克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。你必须先将他们的工作拉取下
来并将其合并进你的工作后才能推送。------学习git分支

推送到远程创库和提交的区别:

提交只是将文件从本地暂存区提交到本地仓库

推送到远程仓库才会让文件被送到远程仓库

而文件被推送之前一定要先被提交

撤销push

1,回退到指定节点即可

链接

soft,mixed和hard

- `--soft` 模式:不会修改工作区的文件,只会将 HEAD 和分支指针移动到指定的 commit 处。
- `--mixed` 模式:将 HEAD 和分支指针移动到指定的 commit 处,并清空暂存区。
- `--hard` 模式:将 HEAD、分支指针和工作区都恢复到指定的 commit 处,这个模式会删除已有的修改和 commit。慎用!
 

参数soft指的是:保留当前工作区,以便重新提交,比如我们这次是修改后重新提交。

也就是soft会删除回退到的节点之前的后的多余节点,但是修改的内容会被保留下来,处于放在暂存区状态。

hard:会撤销相应工作区的修改,一定要谨慎使用,以免出错。

也就是节点删除,修改也撤销。

2,撤销push,将当前节点的修改用上一个节点提交(amend)

相当于当前节点多余生成,需要撤销,然后将当前节点的修改使用上一个节点提交。

(1)git reset --soft "commit_id"

(2)git push --force

git  pull:

git pull用法:
git pull命令的作用是:取回远程主机某个分支的更新(就是这个分支有,而你没有的),再与本地的指定分支合并

一句话总结git pull和git fetch的区别:git pull = git fetch + git merge

git fetch不会进行合并执行后需要手动执行git merge合并分支,而git pull拉取远程分之后直接与本地分支进行合并。更准确地说,git pull使用给定的参数运行git fetch,并调用git merge将检索到的分支头合并到当前分支中。

基本用法:

git pull <远程主机名> <远程分支名>:<本地分支名>
1
例如执行下面语句:

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

后面的冒号可以省略

git pull origin master

表示将远程origin主机的master分支拉取过来和本地的当前分支进行合并

注意:如果远程主机名之后只有一个分支,那是远程的分支,而本地的分支是当前工作的分支

git fetch

有一点很重要,需要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。

刚创建的目录中git fetch

为什么当你创建一个目录,没有git init,也没有创建分支时,git fetch之后什么都没有。

没有git init,没有本地仓库,fetch过来的数据没有地方存放。

git  push发生错误:

原因:是因为我们的本地仓库,与远程仓库的内容不一致导致的。为此在我向远程库推送的时候,要先进行pull,让本地新建的库和远程库进行同步,保持一致。

解决:

1,git pull peername branch

2,git pull --rebase peername branch

git pull和git pull --rebase的区别

第一种方法如果不行,报错:

就使用第二种方法 

git pull拉去后怎么解决冲突

什么是拉去后的冲突

本地和远程都有修改,怎么拉取和合并

先藏匿自己的修改---再拉取---显示修改---修改冲突--提交--推送

链接

拉取后,本地和远程都有修改,但是没有合并怎么办

git stash 自己的修改;

git merge origin(git merge origin/<branch_name>);合并远程分支的修改

git stash apply

如果有冲突---修改冲突。

没有的话git stash apply会自动合并;

再次提交推送。

git stash

查看储藏的历史

git stash list

git stash apply

1,apply之后没有stash@{n},表示应用第一条储藏;

2,apply后指定应用哪一条储藏:

git stash apply stash@{1}

git reset

1,回退到指定节点即可

链接

教程

git reset --hard HEAD

HEAD标识当前已经提交的节点。

作用:如果你在当前节点做了修改,但是都不想要了,都删除,可以使用这个命令。

有时候,我们在错误的目录cmake .. ,导致当前目录下的文件都被删除了,可以使用这个命令恢复当前节点的数据。

git文件删除:

 1,删除工作目录的文件

rm filename

删除工作目录的文件,会对

2,删除版本库文件:

git rm filename

从版本库删除的同时也从工作目录删除了

3,删除暂存区文件:

git rm  --cached filename

作用:从暂存区删除,但还在工作目录

4,撤销提交

链接

文件还原(撤销):

每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。

git文件版本还原:

git checkout -- test.txt

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

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

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

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

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

git checkout-- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令,

文件add的时候就会产生版本。不同次的add就会产生不同的版本。

取消暂存(从暂存区撤出)

git reset HEAD filename

把添加到暂存区的文件撤回到工作区

git clean

git clean -f -n .

忽略文件

.gitignore文件

1,.gitgnore设置在哪里

2,.gitignore是不是只能有一个

3,.gitignore怎么设置

1,.gitgnore设置在哪里

在工作目录设置一个就可以了

(其他目录下也可以设置)

2,.gitignore是不是只能有一个

3,.gitignore怎么设置

.gitignore文件是用来告诉Git哪些文件和目录不需要被跟踪和纳入版本控制的,具体的写法如下:
#忽略所有的.class 文件                  *.class
#_忽略所有以tmp开头的文件夹       tmp*/
#忽略所有的.log文件                       *.log
#忽略.idea文件夹及其子目录和所有文件         .idea/

#忽略.idea文件夹及其子目录和所有文件         .idea/*
#忽略所有的编译输出文件               build/
#忽略所有的 DS_Store 文件            **/.DS_Store
#忽略指定文件或文件夹,               例如ignore.txt或my_folder/ignore.txt
my_folder/
注意:

1,需要或略的文件必须要在add暂存之前写入.gitignore文件,如果是在add之后再写入.gitignore文件无用。

2,每条规则占用一行,以“#”开头的为注释行。其中,“*”代表任意数量的字符,“?”代表任意一个字符,“/**/”代表匹配任意数量的子目录。

git分支

Git分支:
git保存的不是文件的变化或者差异,而是一系列不同时刻的文件快照(想象一下,给一张桌子拍一张照片,纪录了桌子上所有物品的位置、状态,这样就可以称之为快照了。 
我们不必存储所有的物品,只需存储这个照片就可以了,下一次想恢复以前的状态的时候,只需要翻出当时的那张照片,再把物品按照那张照片里的位置摆放一下就OK了。)

快照,就是一个文件在不同时刻的状态。
记录不同时刻的快照,就是记录文件不同时刻的状态

什么是分支

想要知道什么是分支,必须先知道什么是提交对象(提交节点),因为分支就是一个指向提交对象的指针

提交对象:每一次对文件进行提交(commit)时,git都会产生一个提交对象,并保存这个提交对象。该提交对象包含一个指向文件在暂存区的快照的指针,除此之外,该提交对象还包含很多信息。
每一次产生的提交对象都包含上一次的分支(指针)

默认情况下,执行git init 时,自动生成一个分支master

分支的创建:


git branch 分支名
当前创建的分支指向当前对象
创建分支时 并不会切换到创建的分支

在执行提交之后,即产生节点之后才可以创建分支

创建的分支指向哪个提交对象

当前提交对象

创建的创库git branch不显示分支

链接

Git 又是怎么知道当前在哪一个分支上呢?

HEAD指针指向当前分支
用户可以利用HEAD指针指向其他分支,到其他分支进行操作。


分支切换的命令:

git checkout 分支名


检查分支指向的命令:
git log --oneline -- decorate

创建分支并进入:


git checkout -b 分支名

新建的分支会随着工作的进展不断向前推进(不断指向向新的提交对象),而原来的分支不动

当切换分支时,git会重置工作目录,使工作目录进入到需要进入的分支最后一次提交时的状态。

分支合并:
git merge bran1 (合并当前分支和bran1分支)
分支合并有两种情况:
1、当你试图合并两个分支时,如果顺着一个分支走下去能够到达另一个分支(不能往回走),那么Git在合并两者的时候,只会简单的将指针向前推进(指针右移) ,因为这种情况下的合并操作没有需要解决的分歧--这就叫做"快进(ast-forward) "。

2、第二种就是不能一路走下去可以遇到的,git会进行三方合并工作。

删除分支

git branch -d 分支名

git branch -D 分支名     //强制删除

重命名分支名

1,重命名当前分支:

git branch -m new_name;

2,重命名指定分支:

git branch -m old_name new_name

为远程仓库创建分支

创建并检出到新的分支,将新的分支推送到远程仓库即可。

git push -u oringin dev

git push --set-upstream origin dev

删除远程仓库的分支

 git push origin :要删除的远程分支名

注意:冒号前面的本地分支为空;

git push origin :test

这条命令表示将空的本地分支推送到远端的"test"分支,从而删除该分支

smargit删除远程分支

需要切换到其他分支,界面右键删除分支

git branch -r如果查看远程有哪些分支

git branch -r

远程仓库删除分支后,其他仓库要重新拉取合并,才能保持和远程仓库一致。

git branch -v--查看本地分支和远程分支提交节点是否一致

这个没有远程分支名。

git branch -vv--查看本地分支和远程分支提交节点是否一致

这个有远程分支名。

eg:

* master                    70891b75 [origin/master: 领先 3,落后 3] fix: fix error

70891b75和fix: fix error是当前master分支的commit_id和commit日志。

终端目录显示分支设置

vi ~/.bashrc
# 终端显示当前git分支名称
parse_git_branch() {
    git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
source ./bashrc

该函数名为 `parse_git_branch()`,它使用 Git 命令获取当前分支的名称并将其显示在圆括号中,使其可以附加在您的终端提示符中。

解释如下:

- `git branch 2>/dev/null` 命令获取当前 Git 仓库的分支列表,`2>/dev/null` 表示将任何错误输出重定向到 `/dev/null`,以避免在没有 Git 仓库时显示错误消息。
- `sed -e '/^[^*]/d'` 命令删除不包含星号的所有行,因为星号表示当前分支。
- `sed -e 's/* \(.*\)/ (\1)/'` 命令将星号和分支名称包含在圆括号中并返回该字符串。
 

分支合并

1,git merge branch1;

brach1是需要和当前分支合并的分支。

2,git merge branch2 branch1;

branch2是当前分支,branch1是需要合并的分支。

git merge----合并     git rebase----变基

merge会在当前分支创建一个新提交节点,用来合并两个分支最后的提交节点。

rebase会通过“变基”把其他分支的最后的提交节点作为当前分支的起始节点,重新生成一遍当前分支的所有节点。

rebase会修改当前分支的历史。

链接

合并,变基的本质是什么

合并

我们两个一起合并成为新的一个;

变基

你别动,我在你的基础上改变就行;

区别

合并

1,合并是要合并到当前分支;,

2,

变基

1,将当前分支变到别的分支

2,

会产生什么影响

什么情况使用合并

什么情况使用变基

查看分支指向那个对象:

git log --oneline --decorate

获取当前 git 仓库所在的分支名称

git symbolic-ref --short -q HEAD 的作用是获取当前 git 仓库所在的分支名称。

具体作用如下:

- symbolic-ref:用于查询、修改 Git 仓库中的符号引用。
- --short:获取分支名称时,指定显示的名称为短名称。
- -q:将查询命令的错误信息输出关闭或降为警告提示,让命令更加安静,其结果将不会在输出中出现。
- HEAD:Git 中的 HEAD 是指向当前分支的引用,因此 symbolic-ref 命令带上 HEAD 参数就是指查询当前所在的分支。

因此,执行 git symbolic-ref --short -q HEAD 命令,如果输出不为空,则表示当前所在的分支。如果出现错误,则不会有任何输出。该命令在编写 Git 命令脚本时经常用到。

快进(合并)

没有产生分叉,前进合并就可以。

git合并时没有分叉就选择快进。

链接

链接

查看与当前分支合并或者没有合并的其他分支

查看已经合并的分支

git branch --merge

这个命令输出当前分支的所有直接上游分支,也就是没有分叉的分支。

注意:不是只输出指向同一个节点的分支,而是一条节点线上的所有分支。

查看未合并的分支

git branch --no-merge

查看和当前分支分叉的分支。

查看文件是否合并状态

git status

unmerged:文件名

就是未合并

merged:文件名就是已经合并的。

HEAD

单独一个HEAD

eg:git diff HEAD

表示当前结点。

HEAD~

HEAD~只处理当前分支。

注意:master分支的上一个结点是tmp分支的所在的结点fc11b74, 79f109e才是master的第二个父节点。

HEAD~

当前结点的父节点。

HEAD~1

当前结点的父节点。

HEAD~n

当前结点索引为0,n为当前结点之后的第n个结点。

HEAD^n

这个是用来处理一个由多个分支合并而来的结点和他的各个第一级父节点之间的关系的命名。

查看git diff的案例。

git rebase -i HEAD~n

作用:变基(合并)当前结点到当前结点之前的第n个父亲结点,索引从1开始

`-i` 参数是 `--interactive` 的缩写,表示我们要进行交互式变基。交互式变基是一种在变基操作的同时对提交历史进行编辑的方法,通常用于合并、压缩、移除提交等操作。

git rebase虽然用于合并提交,但是本质上是变基。

git rebase -i HEAD~n

指定需要可以变基合并的所有结点,索引从1开始。

注意:merge的结点计算入内。

在交互式界面中会列出所有选择的结点commit id,最下面是第一个结点,我们可以往上选择删除结点,保留我们需要保留的基结点。

git rebase -i HEAD~

同git rebase -i HEAD~1。

git rebase -i HEAD~4

变基前:

目的:以11111作为基结点,合并前面三个结点。

所以-i 交互界面中,保留tmp和1111,其他的删除。

变基后:

原则:以谁作为基结点进行变基,就~指定到谁的索引,索引从1开始。

注意:基结点不会变,合并后被保留,只是集结点之前的结点被合并。

交互模式下:如果不删除任何结点,那么就表示以第二结点为基结点,重新生成第一个结点。

不删除任何结点:

没有任何变化。

git reset和git rebase的异同

相同点:都可以用于合并结点。

不同点:git reset 回退到旧结点。git rebase 会合并生成新的结点。

git diff

git diff 文件名

查看这个文件工作区和暂存区的区别。

git diff --cached 文件名

查看这个文件暂存区和已经提交的当前结点的区别。

git diff HEAD

查看当前结点工作区和暂存区的区别。

git diff --cached HEAD

查看当前结点暂存区和提交的区别。

git diff HEAD^1

查看当前结点(目标结点)和第一级父节点之间的区别。

git diff HEAD^2

查看当前结点和第二级父节点之间的区别。

git diff HEAD^n

HEAD^n都是表示当前结点至少由n个分支合并而来,如果n超过了来源分支的数量,则:

git冲突

冲突的不同部分含义

在 Git 中,当合并代码时出现冲突,Git 会在冲突的文件中添加一些特定的标记以表示冲突的位置。在 Git 中,`<<<<<<`、`======` 和 `>>>>>>` 之间的内容就是这些特殊标记。

具体来说,`<<<<<<<< HEAD` 代表的是当前本地分支的修改,`=======` 代表的是本次合并的分界线,同时也代表冲突的位置,`>>>>>>> <branch>` 代表的是要合并的远程分支的修改。其中,`<branch>` 表示远程分支的名字。

例如,在下面的示例中,表示的是冲突文件的两个修改分别来自当前本地分支和要合并的远程分支:


<<<<<<< HEAD
This is the code in the current local branch
=======
This is the code in the remote branch
>>>>>>> remote_branch

解决冲突代码之后应该怎么做

需要暂存起来,即git add 。

如果不需要修改,则继续提交。

没有指定分支冲突解决办法pull时的错误

Need to specify how to reconcile divergent branches.

smartgit合并冲突可以直接在界面合并,也可以打开文件合并;

合并完成之后选中冲突的文件之后要暂存;

smartgit拉取远程仓库的分支

 电机远程的分支检出,如果本地没有这个远程分支,就会显示是否创建这个分支。

如何删除远程仓库的文件

github上只能删除仓库,不能删除文件和目录。

删除文件和目录用命令:

1,删除远程仓库,保留本地在

git pull 远程仓库名 分支

dir

git rm -r --cached 要删除的文件或者目录

git commit -m '.....'

git push -u 远程仓库名 分支

2,本地和远程仓库都删除

git log

git log查看commit信息

查看提交历史:

git log

看到每次提交的简略的统计信息:
git log  --stat
git log 的常用选项
选项 说明
-p
按补丁格式显示每个更新之间的差异。
--stat
显示每次更新的文件修改统计信息。
--shortstat
只显示 --stat 中最后的行数修改添加移除统计。
--name-only
仅在提交信息后显示已修改的文件清单。
--name-status
显示新增、修改、删除的文件清单。
--abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
--relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。
--graph
显示 ASCII 图形表示的分支合并历史。
--pretty
使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和
format(后跟指定格式)

查看最近的n次提交

git log -n
git log -1表示查看最近的一次提交。

git log --graph

以图表的方式查看各个分支的情况。

git reflog

当你执行一些更改到分支中,例如合并分支、rebase、reset、stash等操作时,都会影响到 HEAD 的位置,git reflog 可以记录这些变更,你可以使用 `git reflog` 命令来查看这些变更的历史记录。

使用 `git reflog` 命令可以在本地仓库中查看已经被删除的分支或提交。如果你的 Git 仓库被操作过程中意外删除了某个分支或提交,可以使用 `git reflog` 命令查找被删除的提交前的引用,然后进行恢复。

需要注意的是,`git reflog` 命令不会保存历史记录很长的时间,因此如果需要保存历史记录,请及时备份。

git reflog---恢复到指定的提交节点

git checkout HEAD@{n}

头指针在xxxxxx分离

链接

git reflog查看的日志是操作之前的,还是操作完成之后的结点数据

是操作完成之后的。

git worktree

git worktree add 目录

git增加子模块

什么是子模块

怎么制作子模块

smartgit:

 git:

git submodule add url (希望存放的文件路径)

如果之前添加过这个子模块或者子模块以目录的形式添加,再次添加时,报错怎么办

already exits in the index

解决办法:

1,删除之前的子目录或者子模块;

2,重新提交项目,让项目去除旧子模块的index;

3,重新git submodel add url就行。

添加子模块之后的HEAD分离

链接

1,合并分离

在做修改之前,一定要先为HEAD指向的提交创建分支,合并再修改文件。

产生HEAD游离的原因

在Git中,HEAD游离是指HEAD指向了一个分离的状态,也就是HEAD指向的不是一个branch名称,而是某个具体的commit或tag。这往往发生在以下情况下:

1. 检查out具体的commit或tag
通过在本地仓库上使用`git checkout`命令,可以将HEAD指向某个具体的commit或tag,以用于查看代码库的某个历史版本。当HEAD指向的是一个具体的commit或tag时,就会出现HEAD游离状态。

2. 分支被删除
当HEAD所在的分支被删除时,HEAD将会指向commit或tag,这时就会出现HEAD游离状态。

3. 合并冲突
当在合并分支时,出现了冲突,但尚未解决冲突时,HEAD将指向合并的commit。如果在解决冲突前离开了该分支,就会导致HEAD指向一个具体的commit而不是分支,进而引起HEAD游离。

因为HEAD游离意味着你当前的代码不位于任何分支上,所以这对于后续commit和代码更新会带来一些问题。推荐在HEAD游离时,恢复所在的分支或者继续commit和push新的变更,以确保代码库的健康和稳定。

添加子模块产生HEAD游离的原因

添加子模块后,子模块中没有分支跟踪改动。

主项目的更改提交和子模块的更改提交

如果我们在主项目中提交并推送但并不推送子模块上的改动,其他尝试检出我们修改的人会遇到麻烦, 因为他
们无法得到依赖的子模块改动。那些改动只存在于我们本地的拷贝中。
为了确保这不会发生,你可以让 Git 在推送到主项目前检查所有子模块是否已推送。 git push 命令接受可以设
置为 “check” 或 “on-demand” 的 --recurse-submodules 参数。 如果任何提交的子模块改动没有推送
那么 “check” 选项会直接使 push 操作失败。

 2,推送

最简单的选项是进入每一个子模块中然后手
动推送到远程仓库,确保它们能被外部访问到,之后再次尝试这次推送。 如果你想要对所有推送都执行检查,
那么可以通过设置 git config push.recurseSubmodules check 让它成为默认行为。


推送的原理

子模块是单独,独立的模块,需要单独推送,先推送所有的子模块,再推送项目;

子模块的删除

链接1

链接2

.gitmodules文件直接删除

git show

显示 Git 仓库中最新提交的时间戳

git show -s --format=%ci 的作用是显示 Git 仓库中最新提交的时间戳。

具体作用如下:

- git show:用于显示某个 Git 对象的信息。
- -s:指定 git show 命令只显示提交信息中的摘要行,而不是完整的提交信息。
- --format=%ci:用于控制 git show 命令所输出的提交信息的格式,其中 %ci 是格式控制符,用于输出提交的时间戳。

因此,执行 git show -s --format=%ci 命令,将会输出 Git 仓库最新提交的时间戳信息。时间戳采用 ISO 8601 标准格式,例如:2019-09-09 15:11:34 +0800。该命令常用于查看某个 Git 仓库最近更新的时间,或者在编写 Git 命令脚本时作为变量参数使用。

 获取指定commit_id的时间戳

git show -s --format=%ci commit_id

git底层

git的实现语言

c语言

git add 生成文件快照

暂存操作会对每一个文件计算校验和,然后把当前版本的文件快照保存到 Git 仓库中(Git 使用 blob 类型的对象存储这些快照),并将校验和加入暂存区域。

每一个文件对应一个blob快照;

blob对象

blob是不是C的结构体

 Blob 对象本身不是 C 语言的结构体。

链接

 

git commit创建tree对象和提交对象

链接

提交对象中的数据

1,包含零个,一个或者多个指向父提交对象的指针;

首次提交是没有直接祖先的,普通提交有一个祖先,由两个或多个分支合并产生的提交则有多个祖先。

2,包含提交信息,比如提交的作者等;

3,指向tree对象的指针。

commit对

链接

tree对象

链接

分支

本质上就是一个指向提交对象的指针;

这个指针的值可变。

创建分支

就是创建指针,这个指针指向当前提交对象。

HEAD指针

永远指向当前工作的指针(分支)

gerrit

git review

拉取change的代码

git review -d(download) chang号;

非分支,正变基

git review提交代码之后产生冲突----提示:非分支,正变基+分支名

原因:提交代码时,   产生冲突;

解决办法:

打开文件---修改冲突---保存--git add -u-----git rebase --continue;

还有冲突---重复以上步骤;

rebase完成之后---git review

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值