git基本操作

一些初始要设置的内容

对命令取别名

---------取别名文件在C:/Users/Administrator/.gitconfig中可以看到。

$git config --blobal alias.ch checkout               //以后用ch就相当于用checkout了

设置vi/vim编辑出现行号
在这里插入图片描述

:数字-----可定位到行
本地账号的设置
image.png
git工具的git bash here窗口可当linux端口操作,可用各程liunx命令,常用的命令

touch test.txt             //创建文件
mkdir test                  //创建文件夹
pwd                          //查看当前目录
cd ..                        //返回到上一个文件夹
cd test                    //进入test文件夹
ll /ls                        //显示当前文夹所有文件
vim test.txt                //编辑文件,ESC退出当前模式,:wq保存退出,:q退出
rm -rf 文件夹/文件名           //删除文件

出现的问题

kex_exchange_identification: Connection closed by remote host Connection closed by 20.205.243.166 port 22
极有可能是我的网络代理的梯子vpn启动了,退出,再删除设置的代理,可以正常,还有可以往下看设置代理,也可处理。

github.com设置代理,提高访问速度

GitHub 是经常的打不开,有时候克隆一个库很久都不下载不下来,很多时候都是超时无法下载,这种情况下我们只有挂代理提高访问速度。
首先你得一个可用的梯子(代理)Elephant
   如果 是socks5(SSR),你需要知道你本地的 socks5 代理 ip 地址和端口,默认打开的话就是 127.0.0.1 端口 6986(我的梯子),然后使用socks5设置代理
   git 有几种传输协议,在Github上主要用到的是Https和SSH协议。所以我们要做的是对git 命令的https 以及ssh流量做代理。
在这里插入图片描述

Git代理有两种设置方式,分别是全局代理和只对Github代理,建议只对github 代理。
   代理协议也有两种,分别是使用http代理和使用socks5代理,建议使用socks5代理。
注意下面代码的端口号需要根据你自己的代理端口设定,比如我的代理socks端口是6987.
全局设置(不推荐)

#使用http代理 
git config --global http.proxy http://127.0.0.1:58591
git config --global https.proxy https://127.0.0.1:58591
#使用socks5代理
git config --global http.proxy socks5://127.0.0.1:51837
git config --global https.proxy socks5://127.0.0.1:51837

只设置 Github 的代理

git config --global http.https://github.com.proxy socks5://127.0.0.1:6986
git config --global https.https://github.com.proxy socks5://127.0.0.1:6986

取消代理

git config --global --unset http.proxy 
git config --global --unset https.proxy

###https连接的github.com 一个token.

//用户名 xiongshaowen
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

设置ssh代理(终极解决方案)
   https代理存在一个局限,那就是没有办法做身份验证,每次拉取私库或者推送代码时,都需要输入github的账号和密码,非常痛苦。
   设置ssh代理前,请确保你已经设置ssh key。可以参考[在 github 上添加 SSH key完成设置更进一步是设置ssh代理。只需要配置一个config就可以了。

# Linux、MacOS
vi ~/.ssh/config
# Windows 
到C:\Users\your_user_name\.ssh目录下,新建一个config文件(无后缀名)

将下面内容加到config文件中即可
   对于windows用户,代理会用到connect.exe,你如果安装了Git都会自带connect.exe,如我的路径C:\APP\Git\mingw64\bin\connect

#Windows用户,注意替换你的端口号和connect.exe的路径
ProxyCommand "C:\Program Files\Git\mingw64\bin\connect" -S 127.0.0.1:6986 -a none %h %p

#MacOS用户用下方这条命令,注意替换你的端口号
#ProxyCommand nc -v -x 127.0.0.1:6986 %h %p

Host github.com
  User git
  Port 22
  Hostname github.com
  # 注意修改路径为你的路径
  IdentityFile "C:\Users\Administrator\.ssh\id_rsa"
  TCPKeepAlive yes

Host ssh.github.com
  User git
  Port 443
  Hostname ssh.github.com
  # 注意修改路径为你的路径
  IdentityFile "C:\Users\Administrator\.ssh\id_rsa"
  TCPKeepAlive yes

保存后文件后测试方法如下,返回successful之类的就成功了。
测试是否设置成功

ssh -T git@github.com   

之后都推荐走ssh拉取代码,再github 上选择clone地址时,选择ssh地址,入下图。这样git push 与 git clone 都可以直接走代理了,并且不需要输入密码。
   很多朋友配置代理之后,可以正常访问github 网页了,但是发现在本地克隆github仓库(git clone xxx)时还是报网络错误。那是因为git clone 没有走你的代理,所以需要设置git走你的代理才行。
设置代理之前
   如果在终端terminal命令行下载软件包速度不快,并不是代理不行,而是在终端terminal也需要进行相应的配置代理,同样的在命令行中git clone 某某工程时,即使终端设置了代理,GitHub也要再配置一遍代理,接下来看操作,命令行敲起来。

[user]
        name = your_name
        email = your_email
[http]
        proxy = socks5://127.0.0.1:1080
[https]
        proxy = socks5://127.0.0.1:1080

给git命令起别名

$git config --global alias.ch checkout
//以后如切换分支,只用ch即可
$gti ch dev

也可以C:/Users/用户名/.gitconfig中写上如下代码,来起别名.用户名我的是windows默认的Administrator

[alias]
     ch = checkout

远程库修改删除操作

  1. 首先本地建一个文件夹mygitremote,git init把该文件夹纳入版本库管理,建六个文件如下图。
    在这里插入图片描述

  2. 与远程库建立关联,并把所有文件放到暂存区

 git remote add oirgin https://github.com/xiongshaowen/mygitremote.git
git add .

在这里插入图片描述
3. 修改
在这里插入图片描述
一。提交,修改,撤回修改
   如果某个文件,已提交,并且对其进行修改,可以放弃修改,还原到提交(刚刚提交的)状态。

git checkout -- hello.txt      //撤回修改
cat hello.txt                      //查看一下文件内容,可以看到没了world hello
-----------------------------------------------提交后查询当前情形-------------------------------------
Administrator@10_0_12_3 MINGW64 ~/Desktop/githubtest/mygitremote (master)
$ git status
On branch master
nothing to commit, working tree clean
---------------------------------修改hello.txt没有add的情形--------------------------------------------------
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   hello.txt
-----------------------------------------撤回修改查看hello.txt--------------------------------------
$ cat hello.txt

---------新建一个文件world.txt,马上放到暂存区,git add world.txt,可以reset或cache撤回到工作区的命令如下,如同上面修改文件没有add的一样。

touch world.txt
git add world.txt 
git reset head world.txt

二,删除已提交的文件
1—git rm命令删除
----use “git restore --staged …” to unstage表示删除的文件可用git restore --staged xxx回到工作区,即表明它现在在暂存区stage.现在只有两个操作了,要么再提交(彻底删除),要么就放在暂存(看不见)

git rm 文件名
例:删除b.txt,后查看状态,显示b.txt在暂存区了

$ git rm b.txt
rm 'b.txt'

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    b.txt

----删除后悔操作,前提是没有提交
------可以先用git status查看当前库的中文件状态,看没没有‘changes to be committed:下面的deleted:xxxx有什么文件“,如有,则可后悔。

$git reset HEAD hello.txt           //恢复到工作
$git checkout -- hello.txt           //回到提交的状态,后悔了。

2—rm 操作系统删除
-----该删除会把文件放到工作区了,想要彻底删除,则要提交到暂存,再commit.
三,重命名 git mv xxx xxx和操作系统mv xxx xxx
1—git mv
-----本质是,先移动文件,复制了一份,再删除旧文件,涉及到了两个文件,从这可以看出,可以恢复旧文件。
例:我重命hellowrld.txt 为hello.txt

$ git mv hellowrld.txt hello.text

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        renamed:    hellowrld.txt -> hello.text

恢复旧文件(后悔了)hellowrld.txt

$git reset HEAD hellowrld.txt   //回到工作区,下面也提示,可以add 了

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   hello.text

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    hellowrld.txt

$git checkout -- hellowrld.txt   //回到提交的状态,新文件还在暂存区,可以提交它
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   hello.text
--------------------------------------------------------------------------------
$ ls
a.txt  abc.txt  hello.text  hello.txt  hellowrld.txt  wrold.txt


2—操作系统 mv xxx xxx
-------操作后,两文件都在工作区了,可以先放到暂存区,再提交,但旧文件删除了,不能恢复了。

$ mv hello.text hellonew.txt

$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    hello.text

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

no changes added to commit (use "git add" and/or "git commit -a")

四,重命名,提交的注释信息(-m后面的信息)
------思路:先查看提交信息

$git log -2      //查看最近两次的提交
Administrator@10_0_12_3 MINGW64 ~/Desktop/githubtest/mygitremote (master)
$ git log -2
commit 826d1bbf637190b07f01f675848c4c1dd84400b1 (HEAD -> master)
Author: xiongshaowen <65179334@qq.com>
Date:   Sat Apr 8 15:25:28 2023 +0800

    fsdaf

commit e3fb20214b2f10bc88344c5fc4d2009ab79f50b0
Author: xiongshaowen <65179334@qq.com>
Date:   Sat Apr 8 15:18:57 2023 +0800

    提交新文件

------再后:修改之(下面是修改最近的一次)

$git commit --amend -m '修改’

[master 0c1eb08] modify
 Date: Sat Apr 8 15:25:28 2023 +0800
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename hello.text => hellonew.txt (100%)

$ git log -2                 //查看最近的两次提交信息
commit 0c1eb083fe77cf86b3e57ba97399c2dfe3583924 (HEAD -> master)
Author: xiongshaowen <65179334@qq.com>
Date:   Sat Apr 8 15:25:28 2023 +0800

    修改

commit e3fb20214b2f10bc88344c5fc4d2009ab79f50b0
Author: xiongshaowen <65179334@qq.com>
Date:   Sat Apr 8 15:18:57 2023 +0800

    提交新文件


-----发布项目时,我们提交只是提交代码如java文件,而一些配置文件是不用提交的,因为如上图中a.properties配置文件里的路径可是不一样的。我放在resources中,别人可能放在其它地方。所有我们上传时要忽略它,不上传。
五,忽略
在这里插入图片描述

例:模拟忽略文件a.properties
首先:,建两个文件a.properties,.gitignore,用git status,可以看到两个没有add的文件

$touch a.properties
$touch .gitignore            //忽略之配置文件
$git status                      //可以看到两个文件


$ git status               //可以看到两个文件处于add之前状态
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore
        a.properties

nothing added to commit but untracked files present (use "git add" to track)

***然后:我们编辑.gitignore文件,加上a.properties,:wq保存退出,再git status,不认识a.properties文件了(这时是没有add的时候)

$vim .gitignore
------------------------------------------------------------------------------------
a.properties                                   //或写 *.properties通配符*表示任意长度的任意字符串
------------------------------------其它常用的正则表达式
*.properties
!b.properties                                    //不忽略b.properties,!常与*一起用。
dir/:                        //忽略dir目录中的所有文件
dir/*.txt                  //饭略dir下的所有txt
dir/*/*.txt
dir/**/*.txt             //忽略任意级别目录下的所有txt
空目录                  //默认忽略
-------------------------------------------------git status-------------------
$ git status

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore

nothing added to commit but untracked files present (use "git add" to track)

分支管理

-----分支在新建的时刻,它里的内容与创建分支的分支一样,如master,后面就各自独立操作。如以master为根据创建分支,此时新的分支内容与master一样,后面就是各不相干。

  1. 新建分支
    -----新建的那时刻,xxxx分支也具有abc…的文件。后来互不相干。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZyaTFGVt-1681960392133)(26419355-056c8012a3b0529c.png)]
    例:以master创建new_branch分支,并切换到new_branch,并马上查看有什么文件
$git branch                               //查看分支情况,带*号的为当前分支
$git branch new_branch             //只创建分支
$git checkout new_branch         //只切换分支
$ git checkout -b new_branch    //创建并切换到分支
Switched to a new branch 'new_branch'
Administrator@10_0_12_3 MINGW64 ~/Desktop/githubtest/mygitremote (new_branch)
$ ls                                //在new_branch中查看有什么文件,可以看到相当于复制一份master的内容
a.properties  abc.txt    hellonew.txt   wrold.txt
a.txt         hello.txt  hellowrld.txt

注意:创建分支,并切换后,如果创建它的地方没有内容,(master没有内容),再切换回master不成功.
在HEAD指回master分支后,需要将工作目录恢复到master分支所指向的内容。但是由于你从开始一直在develop分支上进行操作,master分支对应的工作目录相当于还什么都没有,这样就出现匹配不到任何文件。
-------如何解决
你只需要在初始化一个仓库后,先在master分支上进行一些commit操作,比如增加一个README.md文件,这样就真正创建了一个master分支。

  1. 删除或增加分支内容,再切换分支,看看情况
    假设当前分为new_branch,创建b.properties,c.properties,再add . 再commit提交
$touch b.properties
$touch c.properties
$git add .
$git commit -m "bc.properties"


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c7PTaFBk-1681960392134)(26419355-59b211e7d850f115.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amHQboQk-1681960392135)(26419355-0073ae53bf88bc0d.png)]

  1. 分支删除 git branch -d new_branch
    注意:删除分支,以下情况不可删除
    一,不可自已删除自已
    二,没有合并内容的分支建议不删除,为了保护数据,可以强删除用大写-D。
    -----如上,new_branch增加了两个文件,此时在master下删除new_branch会出错
$ git branch -d new_branch
error: The branch 'new_branch' is not fully merged.
If you are sure you want to delete it, run 'git branch -D new_branch'.

$git merge new_branch               //合并分支,后可以再小写-d删除,合并后的master内容是两个分支合并

git branch -v查看每个分支的提交情况
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EtyxHMHH-1681960392135)(26419355-ecd8dbc627c98931.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kKW4K0YW-1681960392135)(26419355-fdd417f42421039e.png)]
删除分细节:
1—如果在分支A中建一个文件(删除,修改),没有(add,commit),则切换到主分区(如master)中,可以看到A分支创建的文件操作。
2—如果如果在分支A中建一个文件,有(add,commit),则切换到主分区(如master)中,不可以看到A分支创建的文件操作。
3—如果在分支A中建一个文件,没有(add,commit),则切换到主分区(如master)中,可以在主分区中小写-d删除A分支
###分支的合并与冲突

  1. 分支没有冲突的合并。
    ----分支:是一个commit链接,一条长链,通过sha1值链起来,下一个分支可以通过sha1找上父分支。
    image.png
    ---HEAD是一个指针,一直指向commit,所以通过它能回退提交的版本。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NDalzOPN-1681960392136)(26419355-144a0e9fed9320d6.png)]
    ***例:***有一个分支链条,刚开始git init自创建一个主分区,HEAD指向它和它的提交版本,这可以从.git文件夹的HEAD文件中看到 ref: refs/heads/master,同时创建一个a.txt文件,再add . ,commit -m “init”.
$mkdir mygit
$cd mygit
$git init

$cat .git/HEAD
ref: refs/heads/master

$git add .
$git commit -m "init"

然后:建一个分dev,且切换到dev分支,在dev中创建一个文件b.txt,并提交commit -m “dev1”,再git log查看HEADR指向,表明HEAD是跟着commit走的

$ git checkout -b dev
Switched to a new branch 'dev'
$ cat .git/HEAD
ref: refs/heads/dev

$ git log             //在dev分支中可以看到此时HEADR指向dev,dev再指向master的sha1值(239171.……)
commit 2391712725dfaf3381ad45f5ff032d2b0bb56e05 (HEAD -> dev, master)
Author: xiongshaowen <65179334@qq.com>
Date:   Sat Apr 8 22:00:40 2023 +0800

    init

$vim b.txt                  //输入b
$git add .
$git commit -m "dev1"

$git log                                  
commit 5f7d2cb82887dea618eed85d68dfc788e112b412 (HEAD -> dev)
Author: xiongshaowen <65179334@qq.com>
Date:   Sat Apr 8 22:10:22 2023 +0800

    dev1

commit 2391712725dfaf3381ad45f5ff032d2b0bb56e05 (master)
Author: xiongshaowen <65179334@qq.com>
Date:   Sat Apr 8 22:00:40 2023 +0800

    init

$ git checkout master                  // 切换到master分支,查看得到HEAD
Switched to branch 'master'
Administrator@10_0_12_3 MINGW64 ~/Desktop/mygit (master)
$ git log
commit 2391712725dfaf3381ad45f5ff032d2b0bb56e05 (HEAD -> master)
Author: xiongshaowen <65179334@qq.com>
Date:   Sat Apr 8 22:00:40 2023 +0800

    init
 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x3bZjPpc-1681960392136)(26419355-a84934b1660da115.png)]
image.png
dev分支再提交一次

$vim a.txt        //修改主分区创建的文件,加:ab
$git add .
$git commit -m "dev2"
[dev 707e18f] dev2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7IkfESMS-1681960392137)(26419355-83e414f4609e9f1b.png)]
现在master落后,两步了,又不冲突,为了追上dev,可以合并dev两次提交的版本,这叫快进Fast forward

$git checkout master             //切换到主分区
$git merge dev                   //合并分支dev

Git在merge时,默认使用fast forward,也可设置不用,git merge –no-ff 分支
1, 两个分支合并禁用fast forward,不会归于一点commit,主动发起合并的分支,会前进一步)
2, 分支信息完整(不会丢失分支信息),可用git log –graph查看commit信息,就知道了。
----现在我们,又到dev分支进行两次提交 dev3,dev4.又回到master合并dev3,dev4,这次带参数合并,禁用fast forward

$git checkout dev
$vi a.txt               //加点内容
$git add .
$git commit –m “dev3”
$vi b.txt 
$git add .
$git commit –m “dev4”
$git checkout master
$git merge --no-ff dev

从下图可以看出,master发起的两合并,是不同的,第一次归于一点了(在dev2链上,而第二次发起合并,前进了一步,绿线也指示出了分支信息保存了下来)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UGea6aj7-1681960392138)(26419355-120fb0e94721f5c9.png)]

  1. 合并时冲突,要处理冲突

首先:建立冲突场景,分别在上次合并后的各分支中都修改a.txt的第二行内容(两个分支共享一个内容),都各自add . commit .

//假设当前在dev分f支
$vim a.txt                         //第二加 dev
$git add .
$git commit -m "dev"
//切换到 master
$git checkout master
$vim a.txt                //第二加 master
$git  add .
$git  commit -m "master"

然后:到任 一分支中发起合并,我选master中发起,发起后,会产生冲突,如下内容。

//假设当前在master分支,发起合并
$ git merge dev
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-28N8x5lH-1681960392138)(26419355-fef1ee755211de8b.png)]
再然后:处理冲突,即我们可以在一分支中(发起合并的)用vim a.txt 修改即可,删除>>>>>等字样。

$vim a.txt
$git add .
$git com

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UJmI6a9h-1681960392138)(26419355-188d3f3c81407401.png)]
处理完冲突后,再add . commit ,再合并就没问题了,合了后:master会把dev修改的a.txt内容同步进它的a.txt文件,相当于master两次修改提交。还有,如果此时我们再回到dev分支中,来合并master不会出错了,因为master又前进了一步,事实上,只要两个分支处在同一时刻中(每一次merge后,处在同一个时刻中,刚刚创建分支时,两分支也处同一时刻),快进合并就不会产生冲突,如果同一时刻都有修改同一内容,再提交(次数不限,合并都是以最近一次提交为依据合并),再任谁合并谁都会产生冲突

分支的内容版本回退管理

1.版本回退,即版本穿梭
-----我们每执行一次commit,就产生一个版本。执行git log可以看到当前所有的提交记录,也就是每个版本的信息。每个版本都有一个commit id,版本回退的时候,只需要执行git reset --hard commit_id(commit_id不需要输完,输入前6位即可),就可以回退到对应的版本中。
------github有一个HEAD指针,指向当前版本。如下图,最上面的是最新的版本,执行版本回退之后,github只是将HEAD指针指向了历史版本而已。
------如果我们回退了版本之后,后悔了,又想恢复到较新的版本,怎么办呢?由于这个时候执行git log是看不到较新版本的记录的,需要执行git reflog才行。这个时候我们就得到了所有版本的commit_id,再执行git reset --hard commit_id,就可以吃上后悔药,恢复到较新版本了。
image.png

git log -number         //会显示最近三提交版信息
git reflog                   //会显示所有版本id,包括已回退到版本前后版本id,因回版本修改了,后,git log已经不显示回退之前的版本了。
git reset --hard HEAD      //上一个版本
git reset --hard HEAD^   //回退到下一个版本,加多个^可以退回到多个下一版
git reset --hard HEAD~100                     //则是往前倒数第100个版本
git reset --hard commit_id                  //回到版本号(sha1值的前6位即可)的位置,一般先要用git reflog查询版本号。

checkout做版本穿梭,它穿棱后,成为游离状态detached,这时若修改了内容一定要add . commit,不然的话穿棱不回去,游离状态是创建分支的最好时机***
***例:***对分支dev做了四次修改,提交,有多个版本。然后checkout穿棱到版本三,版本三游离出去了,独立的。

$git checkout 版本三sha1值             //游离了,通过git log 查询到commit_jd(sha1)
$vi a.txt
$git add .
$git commit -m "游离时修改了内容,必须提交"
$git checkout mybranch   2735603   //创建分支,并命名,带上sha1值,该值在上面的穿棱时有给出建议
$git checkout master                     //回到现在,

2.管理修改(vi 内容)

不管是在暂存区,还是对象,只要一vi修改,就会回到工作区,但在暂存区时,再修改,它只是复制一份到工作区中,暂存区的不会丢失,只有再add .就会覆盖,可再提交,对象区的一修改不移到工作区了。
举例:建一个版本库mygittest ,git init ----vi a.txt 输入aaa,---->git add . ----git commit -m ‘init’------>vi a.txt 输入内容bbb,这时,对象区中没有内容了。我又把a.txt 放到暂存区,git add .再又修改vi a.txt输入ccc,这时就是如下图所示的情情了。有两份a.txt了,一份在暂存区,可直接提交,一份在工作区(unstage)可以add 了。但查询内容是工作区的cat a.txt
注意!可用:git reset HEAD a.txt,可以把a.txt推回到工作区,相当于移动

$ cat a.txt
aaaa
bbb
ccc


$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   a.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   a.txt


在这里插入图片描述

如上情况。1.放弃工作区修改

$git checkout a.txt
$git commit -m "放弃工作区的ccc,再提交是暂存区的那份,没有ccc内容"

***如上情况。2.放弃对象区修改
----这个时候,内容只是存在于对象区中,这个时候直接执行git checkout – a.txt即可(即把版本库—对象区的a.txt签出到工作区)。注意"–"不能少,不然就是切换分支了,或是把工作区的丢掉。再执行git checkout – a.txt将修改从工作区中删除

$vi a.txt          //输入xxxx
$git checkout -- a.txt           //回车后,仍是对象区中上次提交的样子,等于是没修改

3.删除文件,如何恢复
----假设我们分支里有一个test.txt文件(即已经commit到分支),这个时候我们在工作区中把test.txt删除了,该如何恢复呢?由于版本库中还有test.txt,我们只要把它签出即可:git checkout – test.txt。当然还有另一种情况,就是我们确实是要删掉test.txt的,那么我们需要先执行git rm test.txt,再执行git commit -m "xxx"即可。这和新增修改是一样的。
4.分支管理
方法1,创建分支的同时,切换到新建分支:

git checkout -b dev # dev是新建分支名

方法2:,先新建分支,再切换:

git branch dev
git checkout dev
git branch             //查看当前分支

5.合并分支
想把dev合并到master分支,那么需要先切换到master,然后再merge:

git checkout master
git merge dev

上面的方式是Fast-forward模式,即“快进模式”,直接把master指向当前的提交。这种方式速度快,但是有一个缺点,就是当我们把dev分支删除后,dev分支的信息就丢失了。如果希望保留dev分支信息,可以用–no-ff方式:

git checkout master
git merge --no-ff -m "merge with no-ff" dev

这样相当于新建了一个commit(看到-m这个参数了吗),通过下面的命令,我们可以看到这个commit的信息:下面的显示版本信息比git log 显示的信息简单明了,一行显示一个版本信息。

git log --graph --pretty=oneline --abbrev-commit

这个时候就可以把dev分支删除了:

git branch -d dev

6.分支重命名,master都可重命名,当然了不这样做

$git branch -m master master2

7.stash保存现场

一,建议(规范):在功能没有开发完毕之前,不要commit
二,规定:在没有开发完毕之前,没有commit之前,不能切换checkout 分支(不在同一个commit阶段—merge合并后了的时候,是同一个阶段),这时可以用stash保存现场,再切换。
例:我正在dev分支中开发,没有完毕, 但经理跟我说master分支有任务要做,很急,我就马上切换到master去,又不可提交,因为没做完,所以在此时的dev中保存现现场

$git stash   [现场名]                               //[]表可选
$git checkout master                         //做了活,又回到dev中,此时刚刚没提交的东西看不见,这时我们要恢复现场
$git checkout dev
$git stash list                       //查看现场列表,如果只有一个场,直接下条命令即可恢复
$git stash pop                          //还原现场,并删除现场
$git stash apply              //还原现场,并保存现场 ,若要删除则用 git drop stash@{数字}
$git drop stash@{0}            //删除指定的现场
-----------------------------------------------------------多个现场时---------------------------------------------
$git stash save my1
$git checkout master
$git checkout dev
$git stash list
$git stash apply   stash@{1}          //还原再拨,不删除现场 

***保存现场冲突----如两次退出前保存现地时,修改了同一文件同一行,处理:vi ***

8.tag标签,给版本写标签

--------常用于commit后,
tag标签 :适用于整个项目,和具体的分支没关系
git tag xxx
git tag -a xxx -m “xxxx”
查看标签git tag
删除标签 git tag -d 标签名

$git tag -d v1.0               //删除标签

***例:***现在库中有文件a.txt,两个分支dev master.我在dev中修改了两次文件,提交了两次,也分别打了两个标签。下面看操作。

$git checkout dev
$vi a.txt                       //输入tag
$git add .
$git commit -m "first tag"
$git tag v1.0                   //创建标签1,名为v1.0
$vi a.txt                       //输入tag2
$git add .
$git commit -m "second tag"
$git tag v2.0                             //创建标签2,名为v2.0
$git tag -a v2.0 -m "release Tag"      //创建标签的另一种形式,有注释信息,表明发布版
$git tag                                   //查询所有标签
v1.0
v2.0
$git tag -1 "v*"                      //模糊查询标签,这是查一个,名为v开头的所有标签
v1.0

切换到master,再查看标签,可以看所有标签,表明标签适用于整个库
9.blame:责任

$git blame a.txt     //查看a.txt的所有提交commit sha1值,以及每一行的作者,可以用于追责
^967737a (xiongshaowen 2023-04-10 09:24:24 +0800 1) aaaa
5ba155c2 (xiongshaowen 2023-04-10 09:43:29 +0800 2) bbb

10.diff差异性
-----diff是linux命令,本身不是git的。可以在linux终端式的窗口中用。
例如:下面库中两个文件a.txt,b.txt.,再用diff a.txt b.txt后
在这里插入图片描述

$diff -u a.txt b.txt
--- a.txt       2023-04-10 12:58:45.951439500 +0800               //---表示源文件,+++表示对比的文件,其它是修改日期时间
+++ b.txt       2023-04-10 12:58:45.951439500 +0800
@@ -1,6 +1,7 @@                                        //-表源,+表对比的,从第一行开始比较
 aaaa                                                   
 bbb
-cc                                                   //内容上的加减号表,加上内容到源文件,从源文件减去内容,两个文件内容一样了。
+ccc
 dd
 hello dev
-▒▒▒▒▒▒
+hello dev2
+hello dev3
\ No newline at end of file

-----git diff :暂存区 和工作区的差异,工作区 和 某个对象区的差异,不是不同文件的差距。
例:暂存区,工作区的差距(注:左源,右目标)

vi a.txt                 //输入 first line.....
git add .
git commit -m "init"
vi a.txt                   //输入第二行 sencod line...,此时把对象区的a.txt复制到工作区了
git add .                 //此时此刻,a.txt回到暂存区了
vi a.txt                    //输入第三行 three line ....,此时,把a.txt复制一份到工作区了,不是移动

在这里插入图片描述

现在比较暂存区和工作区的差异

$git diff
warning: in the working copy of 'a.txt', LF will be replaced by CRLF the next time Git touches it
diff --git a/a.txt b/a.txt
index 05e3fe0..1e0185d 100644
--- a/a.txt
+++ b/a.txt
@@ -1,2 +1,3 @@
 first line...
 second line...                     //表明两区的前两行是一样的,因为前面没有符号(+,-)
+three line...                          //+表明暂存区只要加three line...后,都一样了。

现在比较对象区和工作区的差异示例

vi a.txt             //输入 111111111
$git add .
$git commit -m "init"
$vi a.txt              //输入 2222222
$git diff sha1值(“init‘的)

在这里插入图片描述

现在比较 最新的对象区和工作区的差异(HEAD),一定要注意是:左源,右目

$git add . 
$git commit -m "init2"                      //把上次工区的222222提交到对象区
$vi a.txt                             //输入3333333,再马上比较之,
$ git diff HEAD
warning: in the working copy of 'a.txt', LF will be replaced by CRLF the next time Git touches it
diff --git a/a.txt b/a.txt
index 1640270..ce427e6 100644
--- a/a.txt
+++ b/a.txt
@@ -1,2 +1,3 @@
 11111111111
 22222222222
+33333333333

git diff --cached commit的sha1值 : 对象区和 暂存区的差异
git diff --cached HEAD : 最新对象区和 暂存区的差异

本地到远程的操作(推送,拉取)

push:本地->github
pull:github->本地 , pull = fetch + merge

rm -rf * :当前目录中的文件、子文件目录全部删除(不会删除隐藏文件、不过回收站)
.....rm ..... -rf / ......:不要执行,删除整个计算机中的全部文件

github的仓库中,默认的说明文档README.md
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RgXpcG4c-1681960392140)(26419355-f5a0cd8ed548185a.png)]

推送

push: 本地–>远程

  1. 建立与远程的关联。xiongshaowe
    ***首先:***注册一个远程账号(A:6517@qq.com ,xiongsh,cexoit1983.B:106785@qq.com ,xuhui1986,cexoit1983)
    然后:建一个远程仓库git2023(作为此测试用),一般不选初始化一个README.md
    再然后:本地建同名的仓库git2023,再配本地账号,公钥,等,再建一些文件,如a.txt,b.txt
$git init                               //把该文件夹纳入git管理库
$vim a.txt                           //建a.txt文件,输入一些内容
$ git config --global user.name "xiongshaowen"
$ git config --global user.email "65179334@qq.com"
$ ssh-keygen -t rsa -C "65179334@qq.com"       
$ssh-keygen                          //光这个命令也可生成公钥用,
 //在c:/user/Administrator/.ssh中产生公钥文件id_rsa.pub,把内复制到远程官网的new sshkey中,
//公钥一般用于ssh协议连接,这样我们就可用它了,可免密码推送拉取,不过地址是git开头的。
//生成公钥也可
 $ssh -T git@github.com                              //测试可以连通远程官网不,如果成功会出现下面的字符串
Hi xiongshaowen! You've successfully authenticated, but GitHub does not provide shell access.

再然后: 把文件add .,commit ,再建立关联,再后push推送 ,除第一次推送外,后续更新推送只要git push即可,不用带后面的参数。

$git add .
$git commit -m "inita.txt"
$git remote add origin https://github.com/xiongshaowen/git2023.git       //origin是远程库的别名
$git remote add origin git@github.com:xiongshaowen/git2023.git     //ssh协议关联远程仓库,前提是把公钥放进远程账户或库中,推送时,不用写账号密码的。
$git push -u origin master
$git push                         //后续修改推送,不用写上-u origin master了。

如果远程仓库有内容,我们在本地新建了个mygit库,再关联它,再推送,极有可能出错,推送到同一个引用的东西不同了,处理办法是:先整合合并,即本地要先git pull --base origin 分支名(等于fetch +merge+远程根基移到本地了,本地的a.txt相同,没事,不同则可能产生冲突,冲突用vi a.txt去处理之)

$git init
$git add .                        //已有a.txt,远程有a.txt,b.txt
$ git push -u origin master
 //出错了,
To github.com:xuhuifeng1986/mygit.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'github.com:xuhuifeng1986/mygit.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate整合合并 the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
//处理上面的错    
$git pull --rebase origin master
$git push -u origin master

上传一个独立的分支(比如代码是从工程中直接DOWNLOAD ZIP文件如BowlingScore-test.zip,该文件初始下载下来是没有git功能的,与远端没关联分支是独立的),现在在本地创建一个分test,再又上传到远程分支test上(自动新建的。

1、Git init (在本地工程目录下),生成.git 文件夹

$git init

2, 上传修改的文件

git add .

3, (*可替换成具体要上传的文件名,*表示提交所有有变化的文件) 3、添加上传文件的描述

git commit -m "test" 

(”test“为分支名)

4、(创建分支)

git branch test

5、(切换分支)

git checkout test

6、与远程分支相关联

git remote add origin https://github.com/yangxiaoyan20/BowlingScore.git

(”BowlingScore“ 为工程名)

7、(将分支上传)

git push origin test:test

如果上面是https push后,会弹出一个网页,让我们输入:账号,密码(远程的),再又弹出对话框,让我们输入账号,token.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hvae70qG-1681960392140)(26419355-da95a6fd76e5cc82.png)]

https协议两个token

​ 1一个是xiongshaowen 65179@qq.com,cexoit1983

​ 2另一个是xuhuifeng1986,106785@qq.com ,cexoit1983

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 
ghp_BEBaZ14HUHtvjZQOimtUgfRDWGrdmC4MkEr

​          ssh协议,不用输入token,但要生成私钥id_rsa,公钥id_rsa.pub,私钥留本地,公钥复制放到远程仓库或系统中,这样可免密钥推送拉取。本人把C:/Users/Administrator/.ssh与.gitconfig两个文件打包,放进网盘里,用的时候下载解压以原来同样的方式放进相同的目录里,这样在网吧咖啡图书馆,也可直接用,公钥事先搞到远程账里了。

  1. 分支推送布局

dev->test(merge dev)–>master(merge test)
dev:开发分支,频繁改变
test:基本开发完毕后,交给测试实施人员的分支
master:生产阶段——,很少变化(最后合并dev分支)
bugfix:临时修复的分支

origin/master表示远程分支,在我们推送拉取时,我们是与它来感知远程信息的,它处于游离状态,一但修改就要提交

$git remote show        #查询远程服务器
origin                   //当前只有它了
$git remote show origin          //显示远程服务器具体信息
* remote origin
  Fetch URL: git@github.com:xiongshaowen/git2023.git
  Push  URL: git@github.com:xiongshaowen/git2023.git
  HEAD branch: master

$git status
Your branch is up to date with 'origin/master'.       //origin/master表示远程分支,up to date与。。。一样最新的

git remote show origin查看本地与远程库的关系

 remote origin
 // Fetch URL: git@github.com:xuhuifeng1986/mygit.git
 // Push  URL: git@github.com:xuhuifeng1986/mygit.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

git branch -av查看本地与远程分支的情况

$ git branch -av
* master                118a1ad local2
  remotes/origin/HEAD   -> origin/master
  remotes/origin/master 118a1ad local2                   //HEAD指向origin/master,而远程master与本地master指向同一个sha1值

克隆与拉取

        如果本地没有搞仓库,则可以直接从远程克隆来到本地,不过克隆过来的是以远程仓库名命名的文件夹,并放在本地,这个项目就是一个版本库了,该库已经关联了,不用再git remote add去关联了。再进去git操作。
本例:以ssh协议从远程仓库中克隆库到本地,事先已配好了公钥,私钥(放本地),第一次克隆过来,不用git init,克隆后,再进入克隆过来的文件夹中,直接用git等操作。

//$git clone 远程地址 【本地库别名】

$ git clone git@github.com:xiongshaowen/git2023.git    //可写本地库名---可自定义
Cloning into 'git2023'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.

$ cd git2023                        //进入本地版本仓库,已经被初始化了
Administrator@JTCH-096 MINGW64 ~/Desktop/githubtest/git2023 (master)
$

多用户协作开发项目

本例是在一台机子上模拟多用户开发一个项目

​ 一,分别创建本地两个版本库(git init),mygit1分别进入里去,再关联,pull之,git init.也可克隆远程版本库到本地的 一个地方分别命名mygit1和mygit2(如:git clone git@github.com:xuhuifeng1986/mygit.git mygit1 ).

git clone git@github.com:xuhuifeng1986/mygit.git mygit1
git clone git@github.com:xuhuifeng1986/mygit.git mygit2  //两个库已都与远程库关联了

在这里插入图片描述

二,分别为mygit1,mygit2创建–local用户。

$cd mygit2               //mygit1不管了,它利用先前创建的--global用户xiongshaowen
$git config --local user.name xuhuifeng
$git config --local user.email 106784873@qq.com

本地与远程冲突处理

在这里插入图片描述

push/pull:推送,改变指针
-----当在本地mygit1,提交修改,再push后,head指钟指向origin/master(远程库感知库),而origin/master处于游离状态,即可让所有与远程库关联的用户感知,此时别处用户没有pull的情况下,查询origin(git remote show origin)即可看到它提醒该用户要pull(=fetch+merge)的了,你版本过期了(out of date).
image.png

//在网吧的本地库查询origin/master
$git remote show origin

在这里插入图片描述

现在我更新网吧的本地库,git pull不用带参数啥的,因为克隆时已经自动建立远程关联了。
Fast-forward :更新, 如果发现 更新的内容 比自己先一步(commit 的sh1值 在自己之前),则 会自动合并

$git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 228 bytes | 76.00 KiB/s, done.
From github.com:xiongshaowen/git2023
   4a83ff0..dd70d71  master     -> origin/master
Updating 4a83ff0..dd70d71
Fast-forward              //注意,注意
 a.txt | 1 +
 1 file changed, 1 insertion(+)

在这里插入图片描述

制造冲突场景
   现在本人,在云主机上,有一个版本库,本地账号:tenxinyun,在家或网吧有一个版本,本地账号:xiongshaowen,三个地方的库是同名的,并通过推送克隆等操作,内容都一样。

$git config user.name             //查询本地账号名
xiongshaowen
$ls 
a.txt                            //现在库中都有a.txt文件

***冲突的产生:***现在我在腾云主机上修改a.txt的第一行,再add . commit ,push。又在网吧主机上也修改a.txt第一行,再add . commit ,push会出错,不管几次修改提交,只要都是同一时刻的一次push,就会产生冲突了。注意:同一时刻(即两用户的版本库都是一模一样内容的候,一般是pull成功后的时刻)后的这样操作会产生冲突,不是同一时刻的话,只要版本前进或落后pull/push都不会产生冲突
处理冲突:
1.pull
2.fetch+merge
总: pull = fetch + merge
pull冲突处理
   我们直接pull了以后,fetch百分之百分成功,但还会有冲突,这是merge出了错误 ,这时我们要去vi a.txt把文件修改好,再 add .告诉远程,再commit,再push。修改时可能会产生.swap文件,要删除之。
   还没有完,此时腾云主机也要pull一下,才能让两地库达到最新的,即三方都处在一个commit 链点上(sha1值相同)

$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 286 bytes | 95.00 KiB/s, done.
From github.com:xiongshaowen/git2023
   dd70d71..8d66d75  master     -> origin/master
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt         //冲实还有
Automatic merge failed; fix conflicts and then commit the result.
----------------------------------------------------修改:vi a.txt---------------------------------
<<<<<<< HEAD
home网吧冲突产生
=======
home腾云产生冲突
>>>>>>> 8d66d75df2431524360536be19fbcd003becfad7
tenxinyun
---------------------------------------------改好后--------------------------------------------
两个人商量好了,留下腾
home腾云产生冲突
tenxinyun
---------------------------------------------------add . commit push---------------------
$git add .
$git commit -m "网吧处理好了冲突"
$git push
$git remote show origin            //再去查看一下远程情况,没有冲突(conflict)提示了
----------------------------------------------腾云再pull一次,达到三方同处一个commit链点上----------------------------------
$git pull

fetch+merge处理
   在网吧本地库中,先fetch,拉取到本地,百分之百分更新(刚刚腾云主修改了a.txt第二行的内容)到origin/master分支上(游离状的分支),然后,我在网吧本地也修改a.txt第二行,然后也add . commit ,再git merge(合并origin/master,本地master) ,就会看到冲突了,这时,就要商量着修改vi a.txt。再提交,push.最后又到腾云主机去pull了,达到三方同一。

$git fetch
$vi a.txt            //输入:
$git add .
$git commit -m "网吧第二次造冲突,fetch+merget处理"
$git merge            //合并origin/master,本地master,提示有冲突
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.
------------------------------------------------解决冲突之vi a.txt----------------------------
两个人商量好了,留下腾
home腾云产生冲突第二次制造冲突,用fetch+merge处理
tenxinyun
-----------------------------------------------再次add . commit ,merge----------------------
$git add .
$git commit -m ""网吧第二次冲突处理好了,vi a.txt"
$git merge                      //这次可以不用操作,直接push
Already up to date.
--------------------------------------------------push---------------------------------
$git push
----------------------------------------最后,到腾云主机pull------------------------------
$git pull                            //达到三方同一。
"

模拟远程冲突场景都可以在本地制造
1.设一个用户 --local xiongshaowen 65179@qq.com,操作mygit1库。不用担心全局用户重名,因为–local优先级高于system, global.

$git init                       //先初始化mygit1为版本库,利用了全局用户名xiongshaowen,先前做的
$git config --local user.name 'xiongsh'
$git config --local user.email '65179@qq.com'
//本地用户名会在该本库的.git文件中的config中找到
$git remote add origin git@github.com:xiongsh/git2023.git
$vi a.txt                         //如果远程仓库没有东西,等下的提交,push会出错,所以我们先建一个文件,再add .commit,push
$git add .                  //git add *也可将所有文件放进暂存区,但它不能全应到git语法,如忽略设置的东西
$git commit -m "xiongsh init"
$git push -u origin master                    //初次发布,要用到 -u origin master,后续只要git push即可

2.设另一个用户–local xuhuifeng 10678@qq.com本项目用户操作mygit2库

$git init
git config --local user.name 'xuhuifeng'
git config --local user.email '1067@qq.com'
$git remote add origin git@github.com:xiongshaowen/git2023.git
$git pull origin master                       //初次更新远程到本地,要用到origin master或其它分支名,后续只git pull即可

3.sshkey配置,只要一个就可以了,因为它是整个计算机的,但不同的计算机就要别配sshkey了。两个用户都可以用。

git 图形工具

gitk 、gui 、github desktop
   gitk

$gitk

image.png
git gui
   为了看到效果,刚建一个文件(b.txt),没有add. commit等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8AAiMF2p-1681960392142)(26419355-47f0579b0c4a08e0.png)]
   另打开一个git bash here窗口,我们修改暂存区的文件后,再回到gui窗口,点‘Rescan’,可在工作区看到修改了没有提交的文件。
   放入暂存区,点’Stage Changed’
github desktop到desktop.github.com官司网下载
image.png

远程到本地分支管理

  1. 创建分支并关联
    查看远程分支日志和查看地本与远程分支情况
    在这里插入图片描述
$git log origin/master  //或git log refs/remotes/origin/master

$git branch -av                                       //查看本地和关联的远程分情况
* master                a621745 xuhuifeng init         //本地
  remotes/origin/master a621745 xuhuifeng init //本地关联的远程分支,也叫追踪分支

本地到远程

一,如果本地有分支dev,远程没有dev,但关联了master分支

$git branch dev                        //创建本地一个分支dev
$vi a.txt                                      //输入:localcontent
$git add .
$git commit -m "localcontent提交“
$git push                                         //这里没有切换分支的话,仍推送到远程master分支中,
$git checkout dev           //切换到本地的dev分支
$git add .
$git commit -m "dev提交”

$git push                            //直接推送,这样会出错,没有指定远程分支dev,远程没有也没关联
fatal: The current branch dev has no upstream branch.
To push the current branch and set the remote as upstream, use
      git push --set-upstream origin dev
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

$git push -u origin dev                            //这样就推送到了远程自动产生的dev分支中,并关联了(dev<--->origin/dev)
//git push --set-upstream origin dev      //这个与上条语句功能相同
//git push origin dev:dev2                    //可以把本地分支dev推送到远程dev2上。

远程到本地

二,远程有dev分支,本地没有dev
1.git pull :远程–>追踪分支,还没有把dev放到本地来。
2.追踪分到本地:并切换到本地的dev中
      1.git checkout -b dev origin/dev
      2.git checkout -b dev --track origin/dev // -b dev可省略。但两分支不同名,就不能省,一般不这样做。
      3.git pull origin dev:dev2 //不同分支名拉取
      4.git fetch origin dev2:refs/remotes/origin/helloworld //将远程分支dev2拉取到本地并自动创建的本地分helloworld中。

还可以如下那样,把远程分支dev拉取到本地分支devlocal–可自定义名字

git fetch origin devlocal:refs/remotes/origin/dev
  1. 删除
    一,删除本地分支,当然了自已不能删除自已,再删除远程
    格式:git branch -d/-D 本地分支名 删除本地分支
    格式:git push origin src:dset 本地src为空,远程dset为真实分支名,删除了远程分支
       git push origin --delete dset
$git branch -d dev2         //git branch -D dev2强制删除,但远程的dev2还在
$git push origin   :dev2  //删除了远端dev2,git push origin --delete dev2也可删除远程dev2分支

二,先远程删除了分支,本地现在不需要,也要处理之
   1.先查询我们不需要的追踪分支(它是感远程用的)

$git remote prune origin --dry-run
Pruning origin
URL: git@github.com:xiongshaowen/git2023.git
 * [would prune] origin/dev2                                              //提示dev2可以不用了,远程没有了。


        2.清理对应远程删除的分支

$git remote prune

复杂上传拉取

从上面的情况可以得出复杂上传拉取的方法

  1. 从本定指定分支上传到远程指定的分支,没有的话自动创建

    $git push origin master:sprdem    //本地的master分支上传到远程的sprdemo分支上
    
  2. 也可把远程指定的分支拉取到本地指定分支

    $git pull //先同步库
    $git pull origin dev:sprdemo   
    $git pull origin dev:sprdemo --allow-unrelated-histories  //忽略历史,如,处在不同时刻时
    //操作,如刚建库时,初始了一个README.md文件,实际上这是一个提交,而本地刚创建一个库时也有不同的文件,
    //这样建立联容易出这个问题
    

版本标签tag

创建推送
-------------每一次提交(不管什么分支)都可打一个标签。一般用用标识版本性质,如发布版RELEASE,测试版。。。
      git tag v1.0 //简单标签只存储当前commit节点的sha1值
      git tag -a v2.0 -m “我是2.0版” //会产生新的提交即新的sh1值,肯定包侌当前刚刚提交的sha1值。
-------------推送标签
        git push origin v1.0 //在那个分支上推都可看到
        git push origin v1.0 v2.0 //同时推送多个标签
        git push origin --tags //所有都推送

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8c7TVVuD-1681960392143)(26419355-fb1a17b99dd25b33.png)]
image.png
获取标签

$git pull                     //只拉取标签,不要用这个
$git fetch origin tag
$git fetch origin tag v1.0

删除远程标签
一,官网上直接删除
二,命令行删除

$git push origin 空格:v1.0        

远程删除标签后,本地不能用pull感知,要手工删除,pull是前提,一定要执行

$git tag -d v1.0

gitgc压缩文件

先看场景

没有gc之前,.git/refs/heads/
在这里插入图片描述
在这里插入图片描述

$ ll
total 3
-rw-r--r-- 1 Administrator 197121 41 Apr 17 13:09 dev
-rw-r--r-- 1 Administrator 197121 41 Apr 17 12:22 master
-rw-r--r-- 1 Administrator 197121 41 Apr 17 13:16 test

在gc之后(在.git/refs之中执行命令),heads是空的

Administrator@JTCH-096 MINGW64 ~/Desktop/mygit/mygit1/.git/refs (GIT_DIR!)
$ git gc

在这里插入图片描述

其实这些文件没有丢,只是打包放在了.git/packed-refs中了

cd .git
$ll
$ cat packed-refs
# pack-refs with: peeled fully-peeled sorted
ff3f54716fbc3c6068658fb6a5981ffb367ff17a refs/heads/dev
ff3f54716fbc3c6068658fb6a5981ffb367ff17a refs/heads/master
ff3f54716fbc3c6068658fb6a5981ffb367ff17a refs/heads/test
ff3f54716fbc3c6068658fb6a5981ffb367ff17a refs/remotes/origin/master
ff3f54716fbc3c6068658fb6a5981ffb367ff17a refs/remotes/origin/test

裸库,子模块

bare

-------没有工作区的仓库,只存在服务端,是由拉取推送操作,没有add 操作。
例:新建一个文件件夹mygit,

$git init --bare               

在这里插入图片描述

submodule

应用场景:在一个仓库中引用另一个仓库的代码
举例:
**首先:**本地建两个库A,B分别初始化git init,B本地账号xuhuifeng,1067@qq.com.远程也建两个公开库A,B.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5TQZssAj-1681960392145)(26419355-97bd9b42f6dcf475.png)]

git@github.com:xiongshaowen/A.git
git@github.com:xiongshaowen/B.git
$git init
vi a.txt                //aaaa
$git add .
$git commit -m "ainit"
$git remote add origin git@github.com:xiongshaowen/A.git
$git push -u origin master
cd ..
cd B
$git init
$git config --local user.name xuhuifeng
$git config --local user.email 1067854873@qq.com
vi b.txt                //bbbb
$git add .
$git commit -m "binit"
$git remote add origin git@github.com:xiongshaowen/B.git
$git push -u origint master

在这里插入图片描述

现在搞定本地与远程的关系,可以做子模块了,我们是A引用B
-----git submodule add …

cd A
$git submodule add git@github.com:xiongshaowen/B.git
$git add .
$git commit -m "把B库加入了进来:"
$git push

----本地A库的样子
在这里插入图片描述

----远程端的A库的样子
fqp
然后:我修改B库的内容,add . commit push,再分别进入A库git pull,再进入A中的B:git pull,再又返回A:add . commit push.

//进入B库
$vi b.txt                   //输入:modify B reporistory
$git add .
$git commit -m "修改了B库"
$git push
//进入A库,更新B提交的新内容
$cd xxxx/A
$git pull
$cd B                   //当前A库的B库
$git pull
//返回A库根目录
cd ..
$git add .
$git commit -m "把B库的更新更新到远程A库的子库B中“”
$git push

最后:这样我们就得到了一个远程与本地库的引用达到一致了
一下子pull所有子模块
-----当子模块很多时,上面的pull方式很烦锁,可以这样搞

$git submodule foreach git pull

克隆项目怎么把子模块也一起克隆呢?这样做

$git clone ssh地址 --recursive

删除子模块
首先:删除暂存区,主要内容,因为对象区的内容不可删除,修改都是复制一份到工作区,所以先删除暂存区,再告诉对象区
然后:删除工作区,有一些配置文件上传时不会上传的,一直在工作区,如.gitmodules
最后:add . commit ,push

$git rm --cached B
$rm -rf .gitmodules
$git add .
$git commit -m "删除了子模块B"
$git push

substree类似submodule但双向的

substree

与submodule功能相似,但它双向操作,一般建议使用submodule单向的。
在这里插入图片描述

例:paretn,subtree分别为远程和本地建仓库,本地直接初始化,不用克隆,再git remote add xxx建立关联,最后实现parent修改已引入的subtree项目,再实现真正的subtree感知更新,反之亦然,双向的。
一,建立关联与上面submodule方式一样,parent中有a.txt,subtree中有b.txt

//------parent中
$git init
$vi a.txt  //输入:aaaa 或echo aaaa > a.txt ,建一个文件a.txt内容为aaaa
$git add .
$git add commit -m "parent init"
$git remote add origin git@github.com:xiongshaowen/parent.git   //远程库别名为origin
$git push -u origin master             //第一次提交的样子,后续提交只要git push完事了

//------subtree中
$git init
...............
......                      git@github.com:xiongshaowen/subtree.git
......... "subtree init"
.......

二,parent通过subtree命令引入subtree库,引入子模块,这里我们要关联子模块了,首先给远程子模块起别名origin-subtree,方便后面的操作
–squash,会产生新的提交(很容易fast forward(不同分支追赶冲突)点,即fast forwar快进的前提条件是:两个分支提交点的父点是一样的。所以用–squash一定不要一会用,一会儿又不用,如下次更新时又不用–squash--------如$git subtree pull -P subtree origin-subtree master --squash。

    //-------parent中
$git subtree       //查询一下有多少操作

usage: git subtree add   --prefix=<prefix> <commit>
   or: git subtree add   --prefix=<prefix> <repository> <ref>
   or: git subtree merge --prefix=<prefix> <commit>
   or: git subtree split --prefix=<prefix> [<commit>]
   or: git subtree pull  --prefix=<prefix> <repository> <ref>
   or: git subtree push  --prefix=<prefix> <repository> <refspec>

    -h, --help            show the help
    -q                    quiet
    -d                    show debug messages
    -P, --prefix ...      the name of the subdir to split out    
   //-P或--prefix它是关键的引入参数。意思引入进来进行区分开来。

     //引入子模块,这里我们要关联子模块了,首先给远程子模块起别名origin-subtree,方便后面的操作
$git remote add origin-subtree git@github.com:xiongshaowen/subtree.git
$git subtree  add -P subtree origin-subtree master  
$git subtree  add -P subtree2 origin-subtree master --squash   //另一个方式引入子模块,parent中引入第二个子库,
     //-P后的subtree,subtree2是子库名,origin-subtree是远程子库别名 
     //master是分支,即把远程,本地子库引入到本地和远程的父库中。
     //--squash会减少提交次数,如子库subtree2提交了5次,但在父库中只看到一次提交,
         //squash只一次提交是伪的,实际上有两次,先提交所有的(合并),再一次自已提交,往前走了两步
$git push                    //发布到远端,让远端也引入子库

三,本地修改子模块的b.txt,再提交发布后,再更新父库的子库并且再更新远端对应的子库操作如下:注意–squash参数的应用

    //-----parent中
$git subtree pull -P sbutree origin-subtree master
    //或
$git subtree pull -P subtree2 origin-subtree master --squash
     //因为引入子模块到父库子模块subtree2是用了 --squash参数
$git push               //发布更新到远端

四,修改父库中的子库,再更新真正的子库
   如果是在网吧或在其它地方操作,某一天对同样的远端parent,subtree两库操作,可以先克隆到本地git clone ssh/https地址,再分别进入两个目录,不用git init初始化为版本库,但要再次引入子库操作,下面把远程子库关联进父库中:先起别名,再关联进来

 $git remote add origin-subtree git@github.com:xiongshaowen/subtree.git
 $git subtree  add -P subtree origin-subtree master

修改父库中的子库b.txt,add . 提交,发布后,再更新真正子库的b.txt,再同步到远程。
   ***一,***修改parent下的subtree的b.txt,再add,commit,push

cd subtree
vi b.txt                         //输入parent
$git add .
$git commit -m "parent vi subtree"
$git push origin master         //本次不用origin master,可直接push,
    //但它只是更新了自已的,真正的subtree是不可感知
   //要让其感知,则进入parent目录,再push一次

        ***二,***真正的子库subtree更新parent修改的subtree中的b.txt内容.直接pull是不行的.

//但它只是更新了自已的,真正的subtree是不可感知
   //要让其感知,则进入parent目录,再push一次
//------------------parent本地
cd ..                   //假如当前在子库中,进入subtree的上一级目录
$git subtree push -P subtree oirgin-subtree master
//-------------subtree本地
$git pull

这样就同时更新真正子库远端,本地
五,subtree submodule冲突原理与解决
   1.不同的祖先,合并时互相冲突。处理:vi 冲突的文件。
在这里插入图片描述

2.squash冲突,处理:发布和更新都要用squash参数。
image.png

cherry-pick–>commit转移

        场景:写了一半(已提交),发现写错分支了,需要将已提交的commit转移分支等,cherry-pick每一次只转移一个点(本质是复制)。要频频使用git log命查commit sha1值。
image.png

//在需要commit点的分支中,转移
$git cherry-pick sha1值的4位---6位

把写错的分支与正确的分支同步
-----先在正确的分支上,cherry-pick sha1把错的分会提交点移到正确的分支上,然后,checkout sha,删除错分支的提交,再以正确的分支创建分支.
例:master为正确的分支,dev为错的分支.假设master已有a.txt文件,创建了dev分支,忘了切换回master,在dev上修改了两次a.txt,提交了两次,现在想做把写错的分支与正确的分支同步。

$git branch -b dev
$vi a.txt 
$git add .
$git commit -m "first"
$vi a.txt
$git add .
$git commit -m "second"
     //上面提交了两次
$git log
     //查看所有提交的sha1值,事先复制放在一个文件中
$git checkout master
      //切换到正确的分支上,准备转移
$git cherry-pick sha1_1
$git cherry-pick sha1_n
      //.....有几个转移几个,从过云到现在顺序,但是sha1值变了,不是转移前的了,等于多了sha1值
$git checkout dev
      //切换到dev删除提交点,
$git checkout sha1值--最好最初的合点sha1值    //回到写错之前的点
$git branch -D dev
        //删除分支dev
$git branch -b dev 
       //创建dev分支,不用切换到master创建,因为最初创建分的点时,那个commit点是游离状态,游离状时,是创建分支的最好时机。

rebase变基相似cherry-pick

变基—改变分支基础
        与cherry-pick操作的方向相反,它是在写错的分支里面可进行,并且不用一个一个的搞,很方便。
在这里插入图片描述

        rebase会改变提交的历史。变基前的提交点会被遗弃。
image.png
rebase也会冲突
处理:1.vi xxx —> add .—>git rebase --continue
            2.忽略冲突 git rebase --skip
还原生成rebase之前的场景
         git rebase --abort
建议
         rebase分支,只在本机操作,不要推送到远程,不要在master上直接rebase.
举例:
        先初始化一个库mygit,mygit里有一个文件a.txt,有一些容。
先在master分支中更改a.txt(第一行,制造后面的冲突)两次,提交两次,再创建dev分支,并切换到dev,也修改a.txt两次(也是修改第一行,造冲突),再在dev分支中git rebase master把dev所有提交移到master分支上(自动与最近一次提交点后接上)。
        如有冲突,会出错,我们可以用以上三种方式处理冲突,按照上述做法有两次冲
        1.若忽略冲突,可要执行两次git rebase --skip
        2.vi a.txt,修改文件冲突 执行git rebase --continue
        3.放弃变基git rebase --abort

touch a.txt           
vi a.txt                 //输入一些内容,此时还是版本库
$git init                  //纳入版本库,初始化master,不初始化有问题
$git add .
$git commit -m "init"
$vi a.txt             //改第一行
$git add .
$git commit -m "master1"
......
$git commit -m "master2"
$git checkout -b dev           //创建dev分支,并进入dev
$vi a.txt
........................"dev1",,,,,"dve2"
$git rebase master                 //把dev的根基移到master上,


在这里插入图片描述

上面的事做完了,为了让master追上(快进)dev

$git checkout master  //切换分支
$git merge dev   //合并

IDEA操作版本库

  1. idea中操作git命令

在这里插入图片描述

重新启动IDEA可看到控制台的Terminal的git样子

在这里插入图片描述

在这里插入图片描述

  1. 本地的项目上传

    我们建一个.gitignore文件,用于忽略一些文件的上传,建一个README.md用于项目说明。

在这里插入图片描述

在这里插入图片描述

git init
git add .
git commit -m "projectinit"
git remote add origin git@github.com:xuhuifeng1986/MyGradleDemo.git
git push -u origin master

也可于用工具菜单add . commit push

  1. 如果初次克隆项目,有可能是普通文件,还没有构建成项目,这时我们可以右击项目,选如下图菜单:

    选择相应的模板(如maven,gradle会自动,没有选项)

在这里插入图片描述

  1. 更新 gti pull

  2. 如果是本地有项目,现在要与远程库关联,这时候比较复杂了,有可能两方内容不一致,一样的话没问题。不是一样的话,要先建立关联,再git pull,再可以同步了。

处理冲突

现在模拟冲突

  1. 远程修改提交

在这里插入图片描述

  1. 本地修改同一文件同行,提交,再push,会产生冲突

在这里插入图片描述

$ git push
//产生了冲突
To github.com:xuhuifeng1986/MyGradleDemo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'github.com:xuhuifeng1986/MyGradleDemo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for detai
  1. 处理冲突

    首先:见面

    git pull
    
    CONFLICT (content): Merge conflict in src/main/webapp/index.jsp  //冲突的地方
    Automatic merge failed; fix conflicts and then commit the result.
    
    

在这里插入图片描述

然后:修改index.jsp可直接修改,下面的merge修改更好

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZOCTtz3W-1681960392151)(1681724374633.png)]

最后:再add . commit 提交,再push其它用户再用pull更新之

Gitlab配置

-----github只能是开源公开的,想要私人版本,是要收费的。所以我们可以自已搭建私有的免费版本库,功能相当github,有可加入团队,评论等功能。

  1. 下载工具(该工具没有windows版,所以我们只能用linux,我是Centos 7),我们下载ce版,不要下载ee版(收费)
//官网
https://packages.gitlab.com/gitlab/gitlab-ce 
//下载了gitlab-ce-14.0.4-ce.0.el7.x86_64.rpm

  1. 安装配置
    安装说明参考:https://gitlab.cn/install/
  2. 安装和配置必须的依赖项
    一。在 CentOS 7上,下面的命令也会在系统防火墙中打开 HTTP、HTTPS 和 SSH 访问。这是一个可选步骤,如果您打算仅从本地网络访问极狐GitLab,则可以跳过它,我还要做一些的, 我不是本地,是云端,登陆的是root用户,不要sudo。
sudo yum install -y curl policycoreutils-python openssh-server perl
sudo systemctl enable sshd
sudo systemctl start sshd
//下面同步我没做,因为我的防火墙是关闭的
//sudo firewall-cmd --permanent --add-service=http
//sudo firewall-cmd --permanent --add-service=https
//sudo systemctl reload firewalld
  //(可选)下一步,安装 Postfix 以发送电子邮件通知。如果您想使用其他解决方案发送
  //电子邮件,请跳过此步骤并在安装极狐GitLab 后[配置外部 SMTP 服务器],我是要的。
sudo yum install postfix
sudo systemctl enable postfix
sudo systemctl start postfix

    //离线安装rpm,因为在线安装很慢, 已下载上传进/usr/local中
rpm -ivh gitlab-ce-11.5.7-ce.0.el7.x86_64.rpm
EXTERNAL_URL="http://gitlab.example.com"    //外部访问路径,如 ssh -T git@gitlab.example.com
  //除非您在安装过程中指定了自定义密码,否则将随机生成一个密码并
   //存储在 /etc/gitlab/initial_root_password 文件中(出于安全原因,24 小时后,此文件会被第一次 
gitlab-ctl reconfigure 
    //自动删除,因此若使用随机密码登录,建议安装成功初始登录成功之后,立即修改初始密码)。使用此密码和用户名 root 登录。
----------------------------------纯净安装过程,可以打包成installgitlab.sh-------------------
sudo rpm -ivh gitlab-ce-10.8.2-ce.0.el7.x86_64.rpm
sudo yum install -y curl policycoreutils-python openssh-server cronie
sudo lokkit -s http -s ssh
sudo yum install postfix
sudo service postfix start
sudo chkconfig postfix on
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
sudo EXTERNAL_URL="http://gitlab.example.com" yum -y install gitlab-ce
gitlab-ctl reconfigure       //生成gitlab-ctl可执行文件
------------------------------------------------打包成可执行文件的话------------------------
chmod 755 installgitlab.sh
bash installgitlab.sh

二。启动、停止,如果有问题,极有可能是防火墙的问题。

gitlab-ctl start /stop
systemctl stop firewalld             //关闭防火墙
systemctl disable firewalld          //开机启动自动关闭防火墙

三。访问服务器,增加用户(不可能一直用root登陆吧)
首先:登陆(一般输入ip后,会弹出页面让我们修改root密码)

​ 但有时也不会这样的,这时我们要查看初始密码,再root登陆,创建自已常用的账号

# cat /etc/gitlab/initial_root_password                 //初始密码放在这个临时文件中,这个文件将在首次执行reconfigure后24小时自动删除
Password: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

然后:修改root密码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kFx6va1b-1681960392152)(1681957399079.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ofk9w4sT-1681960392152)(1681957418319.png)]

最后:又重新登陆
image.png
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O4s8rh98-1681960392153)(26419355-2dfa14aaf6e35e3c.png)]

  1. 创建用户,创建团队,组里面创建项目(版本库)
    先以root用户登录
    在这里插入图片描述

    后,增加用户,选如下权限(xiongsh,cexoit1983,6517@dqq.com
    image.png

image.png
在这里插入图片描述

image.png
配置SSH key,我一般都打包了一个,本地账号对应的SSHKEY,直接从网盘下载解压,考贝id_rsa.pub内容到gitlab,私钥是本地的
image.png

  1. 测试举例
    -----我们现在创建一个本地仓库mygit,创建一个文件放进去a.txt,再上传发
git init
touch a.txt
git add .
git commit -m "init"
git remote add origin git@gitlab.example.com:myjavaweb/myproject1.git
git push -u origin master    //发布时出现了如下错误

//错误 1 这是一个域名解析错误 ,该域名,我们没有在互联网上注删,只是一个本地域名
ssh: Could not resolve hostname gitlab.example.com: Name or 
service not known
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

   //处理办法:在linux系统中,设置
   //方法1
EXTERNAL_URL="http://ip地址"
gitlab-ctl reconfigrue         //这一步太慢了,最好在安装rpm后做此事,如果已reconfigure,用下面的方法很方便
    //方法2,C:\Windows\System32\drivers\etc\hosts中加入如下内容,ip gitlab.example.com
47.108.50.98 gitlab.example.com
   //方法3:建立远程库关联时,写上公网或局域网ip地址以替代本地域名
git remote add origin git@121.43.32.111:myjavaweb/myproject1.git
//错误2 初次发布时,虽然关联了远程库,但是远程库在创建时自动初始化了有如README.md文件,这时在发布之前先
git pull --rebase origin master
 //再
git pull -u origin master
  • 25
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_33406021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值