Mac~git学习和应用需要注意的几个点

本文详细介绍了Git的各种操作,包括全局和单个项目仓库的用户名邮箱配置、gitdiff、gitadd和gitcommit命令、版本回退、文件删除、SSHkey生成、远程库的添加和删除、创建版本库方式、更新本地版本库、gitignore、多条commit信息的修改和合并、分支管理和删除大型commit历史文件。内容涵盖基础操作和高级技巧,适合Git初学者和进阶者参考。
摘要由CSDN通过智能技术生成

Git学习推荐网站:廖雪峰-Git教程 - 廖雪峰的官方网站,通俗易懂,简单粗暴,就是平俗的语言,好懂、粗暴的那种

git学习进阶~国外经典git学习网站:Git - Book

目录

1. 全局配置和单个项目仓库的用户名邮箱配置

2. git diff命令

3. git add 和 git commit命令

4. 版本回退命令

5. 文件删除rm

6. 创建密钥 SSH key

6.1 生成个人访问令牌

6. 添加远程库

7. 删除远程库

8. 两种创建版本库方式

9. 更新本地版本库

10. git忽略文件

11. 修改和合并多条commit信息

12. 分支管理

 13. git删除commit的历史大文件


1. 全局配置和单个项目仓库的用户名邮箱配置

如果你配置的全局的用户名和邮箱是公司的,而自己也有私人用户名和邮箱来开发自己项目,这样可能一台电脑需要设置多个git用户名配置的项目。如果你不进行配置用户名和邮箱的话, 则会使用全局的, 这个时候是错误的, 正确的做法是针对个人的项目, 在自己的项目根目录下进行单独配置

  • 全局配置

  • 目前大部分公司都已经使用gitlab或github管理项目代码, 在使用git时相信大家都配置了一个全局的用户名和邮箱

$ git config --global user.name "gitlab Name"
 
$ git config --global user.email "gitlab@xx.com"
 
$ git config --list
  • 非公司或非个人的单个项目 

如果你配置的全局的用户名和邮箱是公司的,而自己也有私人用户名和邮箱来开发自己项目,这样可能一台电脑需要设置多个git用户名配置的项目。如果你不进行配置用户名和邮箱的话, 则会使用全局的, 这个时候是错误的, 正确的做法是针对个人的项目, 在自己的项目根目录下进行单独配置

$ git config user.name "mygitlab Name"
 
$ git config user.email "mygitlab@xx.com"

$ git config --list
 

git config --list查看当前配置, 在当前项目下面查看的配置是全局配置+当前项目的配置, 使用的时候会优先使用当前项目的配置
参考原文:https://blog.csdn.net/hyupeng1006/article/details/116154080

  • 删除单个项目的用户邮箱参数,恢复使用全局配置

由于每个git项目下都会有一个隐藏的.git文件夹 ,将终端的工作目录设置到,相应的项目根目录下,执行ls -all命令,显示所有文件,即可看到.git的隐藏文件夹。通过cd .git 进入该目录,发现该目录下有个config文件,采用open config 命令打开,删除个人参数即可:

[user]
    name = XXX(自己的名称英文)
    email = XXXX(邮箱)

保存,command+s 即可。

2. git diff命令

git diff顾名思义就是查看difference,知道了对readme.txt作了什么,这一步查看是在git add xx.file之前,再把它提交到仓库就放心多了

3. git add 和 git commit命令

commit而不是add在git中类似于保存,版本回退就是基于commit保存机制进行的,比如:git reset --hard HEAD(表示当前版本)/HEAD^(表示上一个版本)、--hard commit_id。

git add 文件夹   ~git添加整个文件夹及内容
git add -A 提交所有变化
git add -u 提交被修改(modified)和被删除(deleted)文件,不包括新文件(new)
git add . 提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件

git add . 会把本地所有untrack的文件都加入暂存区,并且会根据.gitignore做过滤,但是git add * 会忽略.gitignore把任何文件都加入

4. 版本回退命令

  • 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file在git add file之前
  • 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>,就回到了场景1,第二步按场景1操作。在git add之后,在git commit之前
  • 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,git reset --hard HEAD^,不过前提是没有推送到远程库。在git commit之后,在git push之前
  • git reflog记录你的git命令,用来寻找回退以前的版本

-->从暂存区恢复工作区,git resotre --worktree readme.txt

-->从master恢复暂存区,git restore --staged readme.txt

-->从master同时恢复工作区和暂存区,git restore --source=HEAD --staged --worktree readme.txt

5. 文件删除rm

$ rm test.txt
rm也算一种修改,提交使用git rm而不是git add
$ git rm test.txt
$ git commit -m "remove test.txt"
git checkout -- test.txt
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

 注意:从来没有被添加到版本库就被删除的文件,是无法恢复的!

6. 创建密钥 SSH key

第1步:在主目录下生成SSH key。

ssh-keygen -t rsa -C "youremail@example.com"

第2步:查看生成的密钥 key

cd ~/.ssh

ls

在.ssh目录里有id_rsa和id_rsa.pub两个文件,id_rsa是私钥,不能泄漏出去;id_rsa.pub是公钥,可以被公开添加到github中。

cat id_rsa.pub  # 查看公钥 

第3步:将公钥id_rsa.pub添加到github中

github -》account settings -》SSH Keys -》add SSH Key

6.1 生成个人访问令牌

Error:如果遇到remote: Support for password authentication was removed on August 13, 2021. Please use a perso

reference:【突发】解决remote: Support for password authentication was removed on August 13, 2021. Please use a perso-CSDN博客这是因该从2021.8.13开始,github不再支持用户名密码验证方式了

需要创建个人访问令牌 (personal access token).

第1步:生成个人访问令牌

github -》setttings -》developer settings -》personal access tokens -》generate new tokens

Note: 生成个人access tokens时要勾选☑️权限,要不然project无法访问知识库! 

第2步:将access令牌添加到项目中

# 修改现有项目的url

git remote set-url origin  https://<your_token>@github.com/<USERNAME>/<REPO>.git

<your_token> 访问令牌;<USERNAME> github用户名;<REPO> 知识库名称 

6. 添加远程库

  • 首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库:

  • 关联本地版本库与远程版本库。
git remote add origin git@github.com:xxx/xxx.git
  • 推送上去。把本地库的内容推送到远程
git push -u origin master

-->我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

--> 强制推送:git push --force 或 git push -f origin master

7. 删除远程库

此处的“删除”其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到GitHub,在后台页面找到删除按钮再删除

如果添加的时候地址写错了,或者就是想删除远程库,可以用git remote rm <name>命令。使用前,建议先用git remote -v查看远程库信息:

$ git remote -v
origin  git@github.com:michaelliao/learn-git.git (fetch)
origin  git@github.com:michaelliao/learn-git.git (push)

然后,根据名字删除,比如删除origin

$ git remote rm origin

8. 两种创建版本库方式

  • 先创建本地版本库再推送远程版本库,git init --> git push
  • 先创建远程版本库再克隆到本地文件夹,git clone

9. 更新本地版本库

git分布式系统的目的就是合作,如果其他人的进度比你快,并且提交了好几次commit to remote repository,现在remote repository的版本领先你本地的版本库了,肿么办?-->更新本地库

  • 先用git fetch到remote repository中获取远程仓库状态和数据更新,获取你本地仓库还没有的数据
  • 然后git merge与本地仓库合并。虽然一般都是合并master,但也可以指定合并分支 <远程repo> <本地repo>:<本地分支>

另一种方法是git pull=git fetch + git merge,它比较简单粗暴,直接硬合并,你无法看到通过git fetch得到的状态更新数据。

--> 怎么git push origin master不好使,git push才行? --未解答

-->git fetch和git pull区别:

Git fetch和git pull区别为:远端跟踪分支不同、拉取不同、commitID不同。

一、远端跟踪分支不同

1、Git fetch:Git fetch能够直接更改远端跟踪分支。

2、git pull:git pull无法直接对远程跟踪分支操作,我们必须先切回本地分支然后创建一个新的commit提交。

二、拉取不同

1、Git fetch:Git fetch会将数据拉取到本地仓库 - 它并不会自动合并或修改当前的工作。

2、git pull:git pull是从远程获取最新版本并merge到本地,会自动合并或修改当前的工作。

三、commitID不同

1、Git fetch:使用Git fetch更新代码,本地的库中master的commitID不变,还是等于1。

2、git pull:使用git pull更新代码,本地的库中master的commitID发生改变,变成了2。

--> 最麻烦的问题:你本地执行了修改操作并commit,远程仓库也被其他人执行了好几次commit操作,造成无法合并的路径、版本冲突了,即both modified same-file,你不能git push、pull或者git merge最新的远程版本库

Your branch and 'origin/main' have diverged,
and have 1 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   README.md

解决方法

  • 一种方法是手动修改Git合并失败的文件为我们希望的内容,再提交
  • 还有一种方法是抛弃本库对冲突文件的修改,全部替换为remote repository文件的内容。
 git reset --hard FETCH_HEAD

10. git忽略文件

  • 全局范围内有效的忽略文件

就是"版本库根目录/.git/info/exclude",全局范围内的所有忽略规则都以行为单位写在这个文件中;

  • 局部范围内有效的忽略文件

就是.gitignore,这个忽略文件只对某一级目录下的文件的忽略有效;

如果某一个目录下有需要被忽略的文件,那么就可以在该目录下手工地创建忽略文件.gitignore,并在这个忽略文件中写上忽略规则,以行为单位,一条规则占据一行;

忽略配置语法:

以斜杠“/”开头表示目录;

以星号“*”通配多个字符;

以问号“?”通配单个字符

以方括号“[]”包含单个字符的匹配列表;

以叹号“!”表示不忽略(跟踪)匹配到的文件或目录;

忽略示例

(1)规则:fd1/*

说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;

(2)规则:/fd1/*

说明:忽略根目录下的 /fd1/ 目录的全部内容;

(3)规则:

/*

!.gitignore

!/fw/bin/

!/fw/sf/

说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录;

(4).idea //忽略.idea文件夹及文件夹下文件

  *.iml //忽略以.iml结尾的文件

参考:Baby小猪,https://www.jianshu.com/p/62a412b7a6e8;git设置忽略文件和目录 - wangmo - 博客园

11. 修改和合并多条commit信息

背景:Git项目,对同一个功能不断改进、多次远程提交生成commit记录的情况,不利于观看。

目的:为了保证一个功能点只有一条提交记录利于后续维护,需要利用git rebase命令对属于同一功能点的多条commit记录进行合并。

rebase需要准备理解rebase的含义!!rebase的含义其实包括选基(rebase commit_id)合并(pick,squash,fixup commit)两步,虽然选基和合并都遵循“前一步原则”,但rebase的commit_id和pick的commit_id绝对不一样!!

rebase的commit_id是要选择几个commits并入的那个commit_id的前一个commit_id;而几条commit_id要并入的那个commit_id是在vim里面的前一条id,用pick标记。即rebase选择的commit_id是所有操作commit_id的基,并不参与任何操作或者并入,比如说commit1、2、3、4,我打算将commit1、2并入commit3,那rebase选择的commit_id是4,commit1、2、3都在vim里面操作!

 具体案例步骤参考:
————————————————
版权声明:本文为CSDN博主「书忆江南」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33588730/article/details/110230039

(1) 确定此次合并基于的base记录

既然要合并“Support”那一条与它上面三条的总共四次commit记录,就要以“Support”那条第一次提交记录的再下面那条“Merge branch”记录,作为本次合并的base记录。这点容易理解,就像造房子需要在地基之上建,第一次提交记录的再之前一次记录就是本次“地基”。因此输入以下命令开始此次记录合并,commit id就是选取的base记录的id:

git rebase -i 4560d5dd728c627291201eb8c04041628de7d5e4

(2) 合并多个commit id

使用git rebase -i命令后,会进入Git内置的vim界面,如下图所示:

vim操作: i--输入模式;esc--证明模式;shift+: +wq--保存退出

commit_id操作命令:reword-编辑commit信息;squash-将commit并入前一个commit中,并保留commit信息;fixup-将commit并入前一个commit中,不保留commit信息等。

--> 单纯地只编辑上一条写错的commit message不合并多个commit信息,可以用:git commit --amend

这四次提交涉及的代码改动都是需要的,但是只需要一条提交记录,因此先按“i”键进入INSERT模式,将后三次commit id前面的“pick”字样改为“s”(我个人用的是f),只有第一次的commit id前面是“pick”,然后按ESC键退出编辑模式,并输入:wq进行保存。注意如果是在Intellij IDEA的Terminal框里编辑rebase信息,那么在按ESC之后光标会回到代码区,此时输入的“:wq”会写到代码里,所以这种情况下按ESC键之后,要重新用鼠标点一下Terminal框里的区域,重新把光标定位回Terminal框中。
(3) 去除多余的commit描述

在上一个pick与squash编辑界面用:wq保存后,会跳出最后的commit描述编辑界面,如下图所示

这里按“i”键进入INSERT模式后,可以把不需要的后三条commit描述用“#”号注释掉,只留下第一次提交时那条蓝色高亮的“Support”描述,然后用ESC键退出编辑模式,再输入:wq进行保存。

(4) 完成rebase

在vim里面的commit操作结束之后,还要继续完成rebase操作,git有三个rebase继续命令:continue、skip、abort

git rebase --continue #表示合并顺利,可以继续完成rebase
git rebase --skip #表示rebase过程遇到冲突,是否要跳过不能合并的冲突
git rebase --abort #表示rebase合并出错,我要放弃这次rebase操作

rebase过程遇到冲突很常见,尤其是本地不同commit版本提交过程产生的冲突,我个人强烈不建议用skip跳过。

--> vi xx.file打开冲突文件,手工修改冲突,然后git add xx.file(表示冲突文件已经手工修改完毕),这时绝不要git commit!!最后,执行git rebase --continue完成rebase操作

在rebase过程中,最好每一步用git status观察rebase状态,输入合适的命令

(5) 远程强制提交

强制提交原因:因为合并多个commit后,本地版本库因为少了几个commits,会与远程库产生different commits冲突,git会建议你用git pull解决本地库与远程库different commits冲突,绝不!

绝不能辛辛苦苦二十年,一朝回到解放前,你git pull了之后,本地库又会被远程库同化为原来的多个commit信息。所以必须在rebase完成后,强制push。

在命令行输入以下命令即可:git push -f origin 分支名git push --force,将远程库的commit记录强制同化为本地库的commit记录。

如果本地分支与远程分支关联过,那么其中“origin 分支名”部分可以省略,强制提交后可以看到GitLab上关于该功能点只有一条commit记录了。

12. 分支管理

Git分支:Git把每次提交(commit)串成一条时间线,这条时间线就是一个分支。

  • 主分支-master分支:master分支的master指针,用master指针指过的提交(commit)串成一条时间线。
  • 指针-HEAD,指向当前分支指针,默认是master分支的master指针。

e.g. 一开始的时候,git用master指针指向最新的提交,再用HEAD指针指向master指针,这样就能确定当前分支,以及当前分支的提交点。

(1)创建分支

创建分支是在当前提交上新建一个分支指针dev,再把HEAD指针指向dev指针,这就表示当前分支在dev上。

git checkout -b dev  # 创建并切换到dev分支
=git branch dev  # 创建分支
 git checkout dev  # 切换到分支dev

或者用switch创建并切换到dev分支

git switch -c dev

(2) 查看分支

git branch

*表示当前分支

(3)切换分支

git checkout master

或

git switch master

(4)合并分支

git checkout master
git merge dev

解决git分支冲突

git status,告诉我们冲突的文件,然后查看冲突文件,Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,删除以前的冲突内容。

git commit -m "conflict fixed",先提交

再执行合并merge

(5) 删除分支

git branck -d dev

 13. git删除commit的历史大文件

problem:如果commit了大文件到本地git repository(即.git文件),则remote github会拒绝整体超过100M的repository推送。因为超过100M是要收费的!

因为大型文件被commit进本地repository了,所以单纯删除commit提交记录一点用也没有,因为大型文件还是存在的

solution:先checkout大型文件,然后通过git rm删除,将repository整理数据量减下来之后,再push到github

第一步:找出本地repository中排名前10的较大文件

git rev-list --all | xargs -rL1 git ls-tree -r --long | sort -uk3 | sort -rnk4 | head -10

比如说:你找出了较大文件

100644 blob 6eb183ae3d234391eb8d0992bf2f69bd53e97153 2382860    data/lda_data/lda2vec_data/topics.pyldavis.npz

第二步:删除本地commit记录

git filter-branch --force --index-filter "git rm -r --cached --ignore-unmatch 'path-to-your-remove-file'" --prune-empty --tag-name-filter cat -- --all

第三步:主动更新本地git repository缓存和历史记录。因为commit记录删除了之后,较大文件还是会在历史记录中存在一段时间,不会马上消失,所以不主动更新的话,git repository整体文件大小不会下降。

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

第四步:强制push到github上的repository

git push -f origin master     #其中master为你要推送的分支

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天狼啸月1990

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

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

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

打赏作者

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

抵扣说明:

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

余额充值