做人呢,最紧要就系开心啦

git基础用法

2,293次阅读
没有评论

以下所有用法以 ubuntu 为例

0.git 是什么?

1. 安装 git

1.1 安装 git 客户端

sudo apt-get install git

1.2. 配置用户和邮箱

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

每个机器都必须带 name 和 email,作为提交者的唯一凭证;
git config 命令的 --global 参数,表示这台机器上的所有 Git 仓库都会使用这个地址

git config --list   // 查看当前配置 

1.3 配置默认编辑器为 vim

ubuntu 上默认时 nano, 我还是习惯用 vi;

git config  --global core.editor vim

2. 本地仓库基本用法

2.1 创建一个本地 repo

$mkdir project;cd project
$git init            // 初始化一个本地空仓库 

2.2 提交一个 commit

(1) 添加文件

$git add readme.txt

git add: 把一个文件添加到 git 系统中,或者说添加到 git 缓存中;git rm: 把版本库的文件或目录删除
git mv: 移动或重命名文件;

提交包括新建,或者修改的文件 (直接编辑);

(2)git status 命令

查看仓库当前的状态

git status  // 查看哪些文件被修改 

git status:
跟踪三类命令
traced, 已跟踪的文件,已经在版本库里;
ignored,被忽略的文件,通常临时文件;
untracked, 未跟踪的文件,通常新建文件属于这一类;

(3) 查看本地文件修改内容

git diff

查看两个指定版本的内容差异:

git log
git diff  vxxx1    vxxx2

(4)add 修改到暂存区

git add .   // 添加当前目录及其子目录下所有改动;git add .../xxx  // 可以 add 指定文件 

(5) 提交修改

add 所有改动到暂存区后,提交到本地仓库;

$git commit -m "wrote a readme file"
git commit -s  // 社区规范,自动添加 Signed-off-by:

2.3 修改最近一次提交

可以将修改文件,或者注释,提交到最近一个 commit(commit-ID 保持不变);

git diff
git add .
git commit --amend
重新修改最近一次提交,如果文件内容为改变,那么只改变 log 信息 

2.4 如何修改最近一个提交的作者

git commit  --amend  --author="leon <leon@qq.com>"

2.5 查看历史版本 log 记录

git log
git log  --pretty=oneline  //log 简短信息
git log --oneline
git log --author=Linus --oneline  // 按行查看某人的所有提交
git log --patch-with-stat  // 查看当前 patch 提交差异,包括文件名和内容
git show xxx_id  // 查看指定 commit_id 的提交差异 

其他用法:

git log xxxx 
xxx 可以是一下:绝对提交名:40 位 16 进制哈希值
符号引用:HEAD 指向最近的提交
相对提交名字:master 表示 master 分支头,master^ 表示 master 分支倒数第二个 commit
范围:符号.. 表示一个范围,master~12..master~10: 表示 master 分支上倒数第 11 和 10 个提交;git log --pretty=short  master~5..master~3  
git log --pretty=short  master~5..master~3  --stat

查看分支合并情况

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

6. 回退到上一个版本

git reset --hard HEAD^
上上个:HEAD^^
上 N 个:HEAD~n

恢复到指定版本

git reset --soft xxxx  // 将 HEAD 引用指向给定的提交,索引和工作内容不变, 只回退 commit, 本地修改保持;如还要再提交,直接 commit 即可;git reset --mixed xxxx : 索引内容跟着改变,工作目录内容不变;git reset --hard xxxx  // 索引和工作内容都改变, 放弃所有修改,回退到 XXX 版本

git reflog:列举历史回退记录,可以查询版本 ID 号 

回退到远程 remote 同步

git reset  --hard  origin/master 

7. 查看工作区和版本库区别

git diff 显示在缓存中或未在缓存中的改动

git diff HEAD -- readme.txt

git diff: 显示尚未缓存的改动:git diff --cached: 查看已经缓存的改动
git diff HEAD 查看所有的改动
git diff --stat 显示摘要 

8. 撤销修改

1) 撤销工作区修改

git checkout -- readme.txt

2) 撤销暂存区修改

git reset HEAD readme.txt   // 撤销指定文件 readme.txt 的 add
git reset HEAD    // 撤销所有 add

3) 若没提交到远程版本库,撤销本次提交

git reset   // 版本回退 

9. 删除文件

1) 删除

git rm test.txt
git commit -m "remove test.txt"

2) 误删: 恢复最新版本

git checkout -- test.txt  // "--" 不能省,否则变成了切换到另一个分支 

3) 从版本库里删掉某文件的版本管理,但是不删除本地文件

git rm -r --cached -n xx.txt  //- n 只是打印,不真正执行
git rm -r --cached xx.txt// 执行 rm 命令,本地文件会保留 

10. 建立一个服务器仓库

server 端:

mkdir  git_test.git

sudo chmod 777 -R git_test.git/
git_test.git/
git --bare init  // 初始化一个服务端的空仓库 

client 端:

git init
git add cpu.txt
git status
git commit -s
git log

ifconfig
git remote  add origin ssh://leon@192.168.0.128:/opt/git_test.git
git remote remove origin  // 删除远程 remote
git remote  -v
git push origin master    // 当前分支 master 推送到远程仓库 origin,同名分支

cd ..

git clone ssh://192.168.0.122:/opt/git_test.git git_test2
cd git_test2/

11. 分支操作

1). 查看分支

git branch
git branch -a
git show-branch -a  // 查看详细分支,和提交信息 

2) 创建分支

git branch <name>
git branch xx/dev 创建分层的分支 

3) 切换分支

git checkout <name>

4) 创建 + 切换分支

git checkout -b <name>

5) 删除分支

git branch -D <name>

// 删除远程分支
git push origin --delete remoteBranchName

6) 合并某分支到当前分支

git merge <name>     //Fast-forward 模式合并,就是直接把 master 指向 dev 当前提交

git merge xxx // 两个分支按提交时间顺序合并
git rebase xxx // 站在另一个分支的肩膀上

按时间 abcdefg
a-b-c-e
   \d-f-g

qgit  --all
图形化查看 git commit

用途:当需要合并别人修改,考虑用 merge
当你的开发工作或者提交的补丁需要基于某个分支之上,用 rebase 命令,比如向内核社区提交补丁;

用 --no-ff 强制禁用 Fast forward 模式
开发中,一般 master 分支用来发布版本,而开发工作在各自的 dev 分支开发并提交,只有稳定版本才合并到 master

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

这样普通模式合并后,就有历史分支信息,能看出来曾经做过合并;

12 解决冲突

1) merge 方式

git merge dev

git merge debug
Auto-merging dev.c
CONFLICT (content): Merge conflict in dev.c
Automatic merge failed; fix conflicts and then commit the result.
leon@leon:~/lab03_merge$ vim

vim dev.c  // 手动修改

git status
git add .
git merge --continue   // 继续 merge

2)rebase 方式

git rebase dev

$ git rebase debug
First, rewinding head to replay your work on top of it...
Applying: malloc 100bytes
Using index info to reconstruct a base tree...
M       dev.c
Falling back to patching base and 3-way merge...
Auto-merging dev.c
CONFLICT (content): Merge conflict in dev.c
error: Failed to merge in the changes.
Patch failed at 0001 malloc 100bytes
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
leon@leon:~/lab03_rebase$

git am --show-current-patch
vim dev.c // 手动修改
git add dev.c
git rebase --continue  // 继续 rebase
git log

3)patch 方式

git format-patch -1
生成 0001-dev-malloc-100-bytes.patch

git checkout  master
git am 0001-dev-malloc-100-bytes.patch
查看 patch
vim .git/rebase-apply/0001

git apply .git/rebase-apply/0001  --reject  // 生成改动文件

// 手动修改
vim dev.c  dev.c.rej
git add dev.c
继续 patch
git am --resolved
git log

13. git revert 把某个提交给撤销

git revert master~3
a-b-c-d-e-f-g  master
-->
a-b-c-d-e-f-g-d' master

14.git cherry-pick 摘草莓

从某个 git tree 或分支上摘取一个 commit 到当前分支
把 dev 的 f 节点 commit 摘到 master 分支上

a-b-c-d-e-f-g-h  dev
   \v-w-x-y-z    master
git checkout master
git cherry-pick dev~2

a-b-c-d-e-f-g-h  dev
   \v-w-x-y-z-f'    master

15 管理远程仓库

git remote 命令

git remote -v  // 查看远程仓库地址
git remote add name_xxx 添加远程仓库地址
git remote show xxx // 查看远程仓库的所有信息
git remote update // 抓取远程版本库中所有可用更新到本地仓库里面
git fetch xxx // 抓取远程 xx 版本库到本地 

添加和删除远程分支

添加:

git push 远程主机名 本地分支名:远程分支名
git push orgin master
git push origin master:dev  // 若 dev 不存在,就新建一个远程 dev 分支 

删除:

git push 远程主机名 : 远程分支名
git push 远程主机名  -d 远程分支名 

拉取远程指定分支:

git pull 远程仓库门 远程分支名
git pull linux linux-5.13

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

命令格式如下:

git push < 远程主机名 > < 本地分支名 >:< 远程分支名 >
// 如果本地分支名与远程分支名相同,则可以省略冒号:git push < 远程主机名 > < 本地分支名 >

实例
以下命令将本地的 master 分支推送到 origin 主机的 master 分支。

$ git push origin master

相等于:

$ git push origin master:master

如果本地版本与远程版本有差异,但又要强制推送可以使用 --force 参数:

git push --force origin master

推送标签到远程仓库

默认情况下,git push 并不会把 tag 标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。

1.push 单个 tag,命令格式为:

git push origin [tagname]

$ git push origin tag_20170908 // 将本地 tag_20170908 的 tag 推送到远端服务器 

2.push 所有 tag,命令格式为:

git push [origin] --tags

git push --tags
或
git push origin --tags

git 如何将本地分支同远程分支进行关联

将本地分支同远程分支进行关联,可以分为以下 2 种情形:

情形 1:

本地已经创建了分支 dev(以 dev 为例,下同),而远程没有
可以通过以下 2 种方法在远程创建分支 dev,并与本地分支进行关联:

 方法 1:git push -u origin dev
方法 2:git push --set-upstream origin dev

情形 2:远程已经创建了分支 dev, 而本地没有

在本地创建分支并与远程分支进行关联,也有 2 种方法:
方法 1 分为两步:

step1: 先将远程分支 pull 到本地 git pull origin dev
step2: 再在本地创建分支并与之关联,又有 2 种方法
(1)git checkout -b dev origin/dev
(2)git checkout -b dev --track origin/dev #可以简写为 git checkout --track origin/dev

方法 2:可以在 pull 远程分支的同时,创建本地分支并与之进行关联

git pull origin dev:dev------- 两个 dev 分别表示远程分支名:本地分支名 

12.github 远程仓库

1) 创建 SSH Key

cd ~/.ssh
ssh-keygen -t rsa -C "youremail@example.com"
一路回车会生成 id_rsa 和 id_rsa.pub 两个文件
id_rsa 是私钥,id_rsa.pub 是公钥

登陆 github.com,选择 setting/ssh keys/
添加 SSH key
把公钥 id_ira.pub 内容复制过去

2)gitHub 上创建一个仓库,然后把本地仓库与之关联,进行同步

git remote add origin git@github.com:luteresa/testgit.git // 关联一个远程库,远程库名字 origin
git push -u origin master // 推送 master 分支所有内容到远程 origin 仓库的 master 分支

3) 从已经存在的远程仓库克隆
git clone git@github.com:luteresa/gitskills.git
... // 本地代码管理操作
git push -u origin master // 推送到远程仓库
// 加上 "-u" 参数,Git 不但把本地的 master 分支内容推送到远程的 master 分支,还会把它们关联起来,以后推送或者拉取时就可以简化命令;
git push origin master

13. 过滤不需要提交到仓库的文件

在工作区目录下创建.gitignore 文件,提交到仓库则生效
https://github.com/github/gitignore
GitHub 做好了很多文件,可以稍加修改拿来用;
如果文件被.gitignore 过滤掉,但又确实想添加,可以强制添加

git add -f file.txt

或者发现无法提交,可能是.gitignore 写的有问题,可以查询哪个规则写错了

git check-ignore -v file.txt

17.BUG 分支,“储藏”现场

每个 Bug 都可以通过临时分支来修复,修复后合并分支,然后删除临时分支;
比如接到临时 bug 任务 issue-101, 先将工作现场临时“储藏”起来,修复后,再恢复现场

git stash

这是用 git status 查看工作区是干净的,因此可以放心创建临时分支

git checkout -b issue-101

在 issue-101 上修复 bug,提交;

git add;
git commit -m "fix bug 101"

修复完成后,切换到 master 分支,完成合并,删除 issue-101 分支

git checkout master
git merge --no-ff -m "merged bug fix 101" issue-101
git branch -d issue-101

完成后,切换到工作区继续干活

$ git checkout dev
Switched to branch 'dev'
$ git status
# On branch dev
nothing to commit (working directory clean)

工作区是干净的,恢复储藏代码

git stash list

两种方式恢复:

1)git stash apply;  // 恢复工作区内容
git stash drop;     // 删除 stash 内容
2)git pop           // 恢复的同时把 stash 内容删掉

git  stash list 查看

可以多次 stash,然后恢复制定 stash
@git stash list
stash@{0}: WIP on dev: 6224937 add merge
git stash apply stash@{0}

18.Feature 分支

添加定制新功能时,为不影响主干代码,可以建立 featurea 分支,完成后合并,最后删除 feature 分支
Feature 分支操作与 BUG 分支类似,当在没有合并之前,if 删除,就会丢失掉修改,如果要强行删除,

git branch -D featrue-branch

19. 多人协作

1). 查看远程库信息,使用

git remote -v;

2) 本地新建的分支如果不推送到远程,对其他人就是不可见的;
3) 从本地推送分支,使用

git push origin branch-name

如果推送失败,先用 git pull 抓取远程的新提交
4) 在本地创建和远程分支对应的分支,使用

git checkout -b branch-name origin/branch-name

本地和远程分支的名称最好一致;

5) 建立本地分支和远程分支的关联,使用

git branch --set-upstream branch-name origin/branch-name

6) 从远程抓取分支,使用 git pull,如果有冲突,要先处理冲突

20. 标签管理

1) 标签与分支类似,是指向 commit 的指针,但是标签不可移动;
2)TAG 就是给个容易记的名字,与原来某个 commit 绑定一定;

3) 默认创建标签给 HEAD,也可以指定一个 commit
git tab v1.0
git log --pretty=oneline --abbrev-commit
git tab v0.9 ea7edc2
git show v0.9

4) 可以指定标签信息
git tag -a v0.1 -m "version 0.1 released" 3628164

5) 可以用 PGP 签名标签
git tag -s -m "blablabla..."
签名采用 PGP 签名,因此,必须首先安装 gpg(GnuPG),如果没有找到 gpg,或者没有 gpg 密钥对
git show 可以看到 PGP 签名信息
用 PGP 签名的标签是不可伪造的,因为可以验证 PGP 签名。

6) 修改标签,可以删除
git tag -d v0.1

7) 推送标签到远程
git push origin v0.1
一次性推送所有未被推送到远程的标签
git push origin --tags

8) 标签已推送远程,删除方法
git tag -d v0.1 // 本地删除
git push origin :refs/tags/v0.1 // 再 push 远程删除

21. 使用 GitHub

1) 在 GitHub 上,可以任意 Fork 开源仓库;
自己拥有 Fork 后的仓库的读写权限;
可以推送 pull request 给官方仓库来贡献代码;
1)

22. 关联本地仓库与远程仓库

1)git remote add origin http://luteresa@192.168.13.168:10009/r/AF_SAMPLE.git
2)git pull origin master
3)git push -u origin master

23. 本地仓库与多个远程仓库了关联
1) 查询本地仓库的远程关联
~$ git remote -v
origin ssh://admin@192.168.13.168:29418/AF_SAMPLE.git (fetch)
origin ssh://admin@192.168.13.168:29418/AF_SAMPLE.git (push)

2)add 关联新的远程仓库
git remote add s1_3m ssh://admin@192.168.13.168:29418/S1_3M_AF.git
$ git remote -v
origin ssh://admin@192.168.13.168:29418/AF_SAMPLE.git (fetch)
origin ssh://admin@192.168.13.168:29418/AF_SAMPLE.git (push)
s1_3m ssh://admin@192.168.13.168:29418/S1_3M_AF.git (fetch)
s1_3m ssh://admin@192.168.13.168:29418/S1_3M_AF.git (push)

3) 推送远程仓库
git push [远程库名] [本地分支名] : [远程分支名]
git push s1_3m s1_3m

4) 从指定远程仓库 pull
git pull s1_3m s1_3m

24. 查看哪些文件是在版本控制下;

git ls-files

25.git 注释换行

git commit -m '
1.it is a test;
2.linefeed;
'

26. 修改文件名

git mv oldname   newname

27. 查询哪些文件在版本控制下

git ls-files

28.fork 之后的本地仓库与原仓库同步;

场景:
在 github,从祖师爷 torvalds 的帐号里,fork 了 linux 的源码;将自己 github 里的 Linux 仓库 clone 到本地供学习研究用;
自己的修改,也会及时提交到 github 仓库,问题来了,一段时间之后,torvalds 的仓库有了很多更新,如何将这些更新同步到个人 github 仓库?

原仓库:https://github.com/torvalds/linux.git
个人仓库:https://github.com/luteresa/linux.git

step1: 在本地仓库添加原仓库为上游代码库

$ git remote  -v
origin  https://github.com.cnpmjs.org/luteresa/linux.git (fetch)
origin  https://github.com.cnpmjs.org/luteresa/linux.git (push)

$git remote add upstream https://github.com/torvalds/linux.git

$ git remote  -v
origin  https://github.com.cnpmjs.org/luteresa/linux.git (fetch)
origin  https://github.com.cnpmjs.org/luteresa/linux.git (push)
upstream        https://github.com/torvalds/linux.git (fetch)
upstream        https://github.com/torvalds/linux.git (push)

由于众所周知的原因,给 github 加下速,添加 upstream2;leon@pc:~/work/myHub/kernel$ git remote  -v
origin  https://github.com.cnpmjs.org/luteresa/linux.git (fetch)
origin  https://github.com.cnpmjs.org/luteresa/linux.git (push)
upstream        https://github.com/torvalds/linux.git (fetch)
upstream        https://github.com/torvalds/linux.git (push)
upstream2       https://github.com.cnpmjs.org/torvalds/linux.git (fetch)
upstream2       https://github.com.cnpmjs.org/torvalds/linux.git (push)

step2, 同步上游原仓库修改到本地;

leon@pc:~/work/myHub/kernel$ 
git fetch upstream2

leon@pc:~/work/myHub/kernel$ git log
commit 8404c9fbc84b741f66cff7d4934a25dd2c344452
Merge: a79cdfb 36f0b35
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Wed May 5 13:50:15 2021 -0700

    Merge branch 'akpm' (patches from Andrew)

        Merge more updates from Andrew Morton:
             "The remainder of the main mm/ queue.

                   143 patches.

可见,本地仓库实际代码尚未同步

查看本地分支:

leon@pc:~/work/myHub/kernel$ git branch  -a
* master
  remotes/origin/HEAD -> origin/master
    remotes/origin/master
      remotes/upstream2/master

step3: 合并上游原仓库修改到本地

$ git merge upstream2/master 

leon@pc:~/work/myHub/kernel$ git log
commit a050a6d2b7e80ca52b2f4141eaf3420d201b72b3
Merge: 1434a31 f8b61bd
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Mon May 24 16:03:24 2021 -1000

可见本地源码已同步到最新

step4: 本地修改推送到 github

git push
git push origin HEAD --force

29git 获取标签对应的版本

git clone 整个仓库后使用,以下命令就可以取得该 tag 对应的代码了
原仓库:
打标签
git tag tag_name xxxx

另外目录:
git clone kernel/ -b tag_name new_dir
但是,这时候 git 可能会提示你当前处于一个“detached HEAD" 状态。

因为 tag 相当于是一个快照,是不能更改它的代码的。

如果要在 tag 代码的基础上做修改,你需要一个分支:
cd new_dir
git checkout -b branch_name tag_name
这样会从 tag 创建一个分支,然后就和普通的 git 操作一样了。

正文完
 1
admin
版权声明:本站原创文章,由 admin 2022-09-03发表,共计11521字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)