git官方文档:https://git-scm.com/docs
基础理解
什么是git?
Git allows and encourages you to have multiple local branches that can be entirely independent of each other.
git在本地维护一个本地仓库,然后使用命令与远端仓库(github、gitee、gitlab)保持同步。
本地工作区(workshop)结构:
基本概念
我们使用命令都是在操作本地的branch、commit。再通过push推到远程仓库。
当命令无法理解的时候,要考虑到是不是因为要兼顾多人尤其是很多人一起开发的场景。
实际上git只有【一条线】用来控制各种提交,包括提交(commit)、合并(merge)、变基(rebase)。
注意到不管有几条线(开了多少分支),在不同线上的每一个点(每一次提交、合并、变基)都不是重叠的。不同的分支(branch)、不同的标签(tag)只不过是git在一次次提交(commit)上面打的标签。
clone
克隆一个新的远程仓库到本地,这样本地就有一个和远程仓库一样内容和信息,包括分支、提交。这个命令一般git提供商都会提供:git clone {remote git repo address}
只克隆特定的分支到本地:git clone --single-branch --branch {branchName} {remote git repo address}
$ git clone -h
-b, --branch <branch> checkout <branch> instead of the remote's HEAD
--single-branch clone only one branch, HEAD or --branch
pull和merge rebase
pull
pull=fetch+merge或者fetch+rebase;
当我们开了很多分支,然后在不同的分支也有了很多次提交之后,会遇到这样的问题:如果有人在主分支上提交了新代码,我们电脑上的代码还是旧的,那我们总不能一直在旧代码上更新我们负责的分支的新功能吧。那我们就需要pull
新的代码到我们的工作区(workshop)
git checkout {local branchName}
git pull origin {remote branchName}
merge rebase
checkout到分支git checkout {branchName}
merge其他分支,把其他分支merge到本分支git merge {branchName}
rebase到其他分支,把本分支rebase到其他分支git rebase {branchName}
图片理解
注意到:My Local Repo里虚线框整个push到Remote Repo
注意到:checkout到哪个分支上操作
本地和远程的关系
注意到:这里的workspace和上面的working directory是一个东西
branch
创建分支git branch {branchName}
查看分支
远程:git branch -r
Acer@DESKTOP-02IGEU4 MINGW64 /d/projects/fupiwu (master)
$ git branch -r
origin/HEAD -> origin/master
origin/component-global
origin/component-tools
origin/hot-fix
origin/master
本地:git branch -v
Acer@DESKTOP-02IGEU4 MINGW64 /d/projects/fupiwu (master)
$ git branch -v
component-global 3b868d9 Merge branch 'component-global'
component-tools fb91175 1.make fetchGetData a individual function; 2.timerange to 20200815;
hot-fix 6014f48 modify readme.md
* master c4a7bc5 1.abort before emit in timeupdate event; 2.add some console.log; 3.modify steps;
远程:git ls-remote --heads
Acer@DESKTOP-02IGEU4 MINGW64 /d/projects/fupiwu (master)
$ git ls-remote --heads
From https://gitee.com/breezingsummer/fupiwu.git
e0c1c5415bf1920e544feb9d4cf21e2b9dbcc768 refs/heads/component-global
fb911754584962be75459e9246b67f19f2404526 refs/heads/component-tools
6014f48a1764a981472b59a4e4349a746ee0668e refs/heads/hot-fix
c4a7bc5bb54a45fc49cb049f794ef6bbf4e69824 refs/heads/master
切换分支git checkout {branchName}
推送分支git push origin {branchName}
tag
给某一次提交打上标签,方便测试和发布。
创建taggit tag -a {tagName} {commit hash} -m "{tagComments}"
查看本地taggit tag -l
查看远程仓库标签git ls-remote --tags
Acer@DESKTOP-02IGEU4 MINGW64 /d/projects/fupiwu (master)
$ git ls-remote --tags origin
dbf351e9906933d751807ff2aef3520481a706d7 refs/tags/v1.0.0
649c05d9abb13e751d48c2e7202d0353202a850e refs/tags/v1.0.0^{}
9cd015b0aa657a60472415347d941c147cee565f refs/tags/v1.1.1
db3bf55fc56255b616331d2fef50ed525f53c025 refs/tags/v1.1.1^{}
2053b778ff732e40060a586dcb2edd00b0099b01 refs/tags/v1.1.2
86f5b685b6cbeeb41321dccea603a1e6555754d0 refs/tags/v1.1.2^{}
0b7634eec8cad133195a4e24e9e58e8edf8e3fc0 refs/tags/v1.1.3
5a36ae9ce21f54e5dce6a75fefd6e283b199518e refs/tags/v1.1.3^{}
634c0c9b9f5eaea04fb524adc96a72df781177a2 refs/tags/v1.2.0
e8c5dc8dd337c74a3b676d4416680ca2ba0402a7 refs/tags/v1.2.0^{}
289a9aedaa7708e01e8b03652205a7228421083a refs/tags/v1.2.1
c4a7bc5bb54a45fc49cb049f794ef6bbf4e69824 refs/tags/v1.2.1^{}
查看标签详情(可以看到tag就是在一次commit上加了标识)(注意到标签的注释和提交的注释是分开的):
$ git show v1.2.0
tag v1.2.0
Tagger: breezingsummer <phil_huangguorong@163.com>
Date: Fri Jul 26 15:06:38 2024 +0800
now we have a fully functioning tools component;
commit e8c5dc8dd337c74a3b676d4416680ca2ba0402a7 (tag: v1.2.0)
Merge: 8fc66ee fb91175
Author: breezingsummer <phil_huangguorong@163.com>
Date: Fri Jul 26 14:58:31 2024 +0800
Merge branch 'component-tools'
切换到tag的代码git checkout {tagName}
推送本地tag到远程仓库
推送单个tag:git push origin {tagName}
推送全部tag:git push origin --tags
删除tag
本地:git tag -d {tagName}
远程:git push --delete origin {tagName}
其他命令
https://blog.csdn.net/to_the_Future/article/details/131560257
回退
深入理解需要深入理解git,直接上结论。
名词解释:HEAD/指向当前状态、index/staging area/暂存区、working tree/working directory/工作目录
注意到:如果已经push到远程了,在本地回退完成后,显然会导致远程仓库的提交和本地不一样。需要git push --force orgin {branchName}
强制推送到远程,以保持远程和本地一致。
还有一种revert,但是会往前生成一个新的提交,一般来讲不是我需要的。我一般需要完全抹去痕迹。
stash,将修改提交到其他分支
背景:我在branch1上修改了代码,后面发现我不想提交在branch1上,我想提交到branch2上。咋办?
困惑点:我总不能再切换到branch2上重新写吧?
解决:我现在在working directory上
- 如果branch1和branch2在同一个提交
那直接切换到branch2上,然后add,commit - 如果branch1和branch2不在同一个提交
stash
将未提交的本地(working directory)修改暂存,然后在其他分支上从stash暂存区还原
提示要么commit,要么stash,才能checkout到其他分支
stash后,生成stash暂存区
可以checkout到其他分支,然后add,commit
以下命令没有{stashVersionName}就默认最新的版本:
stash当前状态
使用默认名字:git stash
给stash版本取名:git stash save {stashVersionName}
查看stash列表git stash list
还原stash
会删除stash的版本:git stash pop {stashVersionName}
不会删除stash的版本:git stash apply {stashVersionName}
删除stash版本
删除一个:git stash drop {stashVersionName}
删除所有:git stash clear
查看stash版本与现在working directory的差异
-p表示显示详细信息:git stash show {stashVersionName} -p
像这种合并(stash、pull、merge、rebase)的操作都有可能会产生冲突,需要手动解决。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。