- 整体结构
- Stash
- stage changes(暂存更改)与 stash changes
- 远程仓库别名
- 合并
整体结构
git:
(这里 stage 就是上图 index)
ps:
Git 可以大概分为三个区
Git 本地数据管理,大概可以分为三个区,工作区,暂存区和版本库。
工作区(Working Directory)
是我们直接编辑的地方,例如 Android Studio 打开的项目,记事本打开的文本等,肉眼可见,直接操作。
暂存区(Stage 或 Index)
数据暂时存放的区域,可在工作区和版本库之间进行数据的友好交流。
版本库(commit History)
存放已经提交的数据,push 的时候,就是把这个区的数据 push 到远程仓库了。
暂存区(Stage)与 index 是同一概念的不同称呼,二者完全等同 。
ps:在 Git 中,暂存区英文名为 stage 或 index,它是位于版本库(.git 目录)中的一个文件(即 .git/index),用于临时存放即将提交的文件改动,记录文件名、文件状态信息(如时间戳、文件长度等),但不存储文件内容(内容存储在 .git/objects 对象库中)。例如,执行 git add 命令时,工作区的改动会被放入这个区域(即 index 文件),为后续的 git commit 做准备。因此,暂存区(Stage)就是 index,二者没有区别,只是同一区域的不同叫法。
原文链接:https://blog.youkuaiyun.com/qq_32452623/article/details/78417609
命令 | 作用 |
git diff | 工作区 vs 暂存区 |
git diff head | 工作区 vs 版本库 |
git diff --cached | 暂存区 vs 版本库 |
Stage 赋予 Git 更多灵活性
以下看起来比较束手无策的场景,只要理解 stage,用好相应命令,都能轻易解决:
修改了4个文件,在不放弃任何修改的情况下,其中一个文件不想提交,如何操作?(没add : git add 已经add: git reset --soft )
修改到一半的文件,突然间不需要或者放弃修改了,怎么恢复未修改前文件? (git checkout)
代码写一半,被打断去做其他功能开发,未完成代码保存?(git stash)
代码写一半,发现忘记切换分支了?(git stash & git checkout)
代码需要回滚了?(git reset)
git reset 回滚命令,带上不同参数就有不同的作用,如下:
命令 | 作用 |
git reset --soft | 暂存区->工作区 |
git reset --mixed | 版本库->暂存区 |
git reset --hard | 版本库->暂存区->工作区 |
原文链接:https://blog.youkuaiyun.com/qq_32452623/article/details/78417609
Stash Changes: (git stash)
Use git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the HEAD commit.
在版本控制中,stage changes(暂存更改)与 stash changes(储藏更改)是两个不同的操作,主要区别如下:
1. 操作目的与效果
- stage changes(暂存更改):
- 相当于执行 git add 命令,将工作目录中已修改或新增的文件放入暂存区(Stage,也叫索引区),标记为 “已暂存” 状态,为后续 git commit 提交到版本库做准备。
- 暂存区的改动会成为下次提交的一部分,提交后会记录到版本历史中。
- stash changes(储藏更改):
- 相当于执行 git stash 命令,将工作目录和暂存区中未提交的所有改动(包括未暂存的修改和已暂存的更改)临时存放到一个独立的储藏空间(stash 栈)。
- 操作后,工作目录和暂存区会恢复到最近一次提交时的干净状态,便于切换分支或处理其他任务,之后可通过 git stash pop 等命令恢复这些改动。
2. 应用场景
- stage changes:
- 当你确认某些改动已完成或达到一个小阶段,希望将其纳入版本控制时,例如:
- 完成某功能模块的代码编写并测试通过,准备提交到版本库。
- 整理好一系列相关的文件改动,希望作为一个提交记录保存。
- 当你确认某些改动已完成或达到一个小阶段,希望将其纳入版本控制时,例如:
- stash changes:
- 当你需要临时搁置当前未完成的改动时,例如:
- 正在开发新功能(未完成且未提交),但突然需要切换分支去修复线上紧急 bug,可先将改动储藏,待 bug 修复后再恢复继续开发。
- 发现当前改动存在问题,想暂时清理工作区以便拉取远程最新代码或重新开始,但又不想丢失当前改动。
- 当你需要临时搁置当前未完成的改动时,例如:
3. 对工作区和版本库的影响
- stage changes:
- 工作区的改动被移至暂存区,工作区内容不变(仍为修改后的状态),但暂存区记录了即将提交的改动。
- 不影响版本库(未执行 git commit 前,改动不会进入版本库)。
- stash changes:
- 工作区和暂存区恢复到上次提交的状态(干净状态),但改动被临时储藏。
- 版本库不受影响,储藏的改动独立于版本库的提交历史。
示例说明
假设你修改了 file1.txt 和 file2.txt:
- 执行 stage changes(类似 git add file1.txt):file1.txt 的改动进入暂存区,准备提交,工作区仍有 file2.txt 的未暂存改动。
- 执行 stash changes(类似 git stash):file1.txt 和 file2.txt 的改动都被储藏,工作区和暂存区回到干净状态,可自由切换分支或进行其他操作。
总之,stage changes 是为提交做准备,stash changes 是临时保存改动以便后续恢复,两者目的和应用场景不同,需根据实际需求选择使用。
ps:
【VSCode Git】stage和stash的区别_stage changes-优快云博客
在 Windows 上安装 Git 也有几种安装方法。 官方版本可以在 Git 官方网站下载。 打开 https://git-scm.com/download/win,下载会自动开始。 要注意这是一个名为 Git for Windows 的项目(也叫做 msysGit),和 Git 是分别独立的项目;更多信息请访问 Redirecting Git for Windows' homepage...。
ps: Git - 安装 Git
定远程仓库(origin)和分支(master)
在 Git 中,使用 git push 命令时,你可能会遇到想要指定远程仓库(origin)和分支(master)的情况。不过,你给出的命令 git -orign -master push 是不正确的,因为它混合了错误的选项和参数。正确的命令格式应该明确指定远程仓库名和分支名,但不需要 - 前缀来分隔它们。
如果你想要将本地的 master 分支推送到名为 origin 的远程仓库的 master 分支上,你应该使用以下命令:
git push origin master
这里,origin 是远程仓库的默认名称(但你可以根据需要更改为其他名称),master 是你想要推送的本地分支名。
请注意,随着 Git 的发展,master 分支名逐渐被认为具有不敏感的含义,并建议改用 main 作为默认分支名。如果你的仓库或团队已经采用了 main 作为默认分支名,那么相应的命令将是:
git push origin main
此外,如果你在 Git 2.28 或更高版本中,并且你的远程仓库已经设置了 main 作为默认分支,git push 命令可能默认推送当前分支到对应的远程分支,这时你可能只需要运行:
git push
但是,为了确保明确性和避免潜在的混淆,明确指定远程仓库和分支名总是一个好主意。
在 Git 中,origin 这个名字是一个默认的远程仓库名称,但它并不是硬编码在 Git 中的,而是在你第一次克隆(clone)一个仓库或者添加一个远程仓库(remote)时设置的。
克隆仓库时设置
当你使用 git clone 命令克隆一个仓库时,Git 会自动将远程仓库命名为 origin。例如:
git clone https://github.com/user/repo.git
这条命令会克隆 https://github.com/user/repo.git 这个仓库,并将远程仓库的引用设置为 origin。
添加远程仓库时设置
如果你没有克隆仓库,而是从一个已存在的本地仓库开始,并希望添加一个新的远程仓库,你可以使用 git remote add 命令,并且为这个远程仓库命名。如果你选择使用 origin 作为名称,那么它就是默认的远程仓库名称。但你也可以选择其他任何你喜欢的名称。例如:
git remote add origin https://github.com/user/repo.git
这条命令会添加一个远程仓库,并将其命名为 origin。
查看和修改远程仓库名称
你可以使用 git remote -v 命令来查看所有远程仓库的名称和它们的 URL。
如果你想要修改远程仓库的名称(比如从 origin 改为 upstream),你可以使用 git remote rename 命令:
git remote rename origin upstream
这条命令会将名为 origin 的远程仓库重命名为 upstream总结
origin 这个名字是在你克隆仓库或添加远程仓库时设置的,但它并不是强制的。你可以根据自己的需要为远程仓库选择任何名称。然而,由于 origin 是默认的远程仓库名称,并且在很多 Git 教程和项目中都被广泛使用,因此它已经成为了 Git 社区中的一个惯例。
合并:
git中的分支非常的轻量,其实就是一个文件,里面记录了分支所指向的commit id,下图中有两个分支分别是master和test,他们都指向了A2这个提交,HEAD是一个特殊的指针,他永远指向你当前所在的位置;有时候你可能不在某一个分支上,不要惊慌,你随时有权利去你想去的分支,git赋予了你新建,切换分支的能力
在git中合并分支有三种方法,分别是merge,rebase,cherry-pick,而其中merge又有三种区别,下面将一一介绍
fast-forward
如果待合并的分支在当前分支的下游,也就是说没有分叉时,会发生快速合并,从test分支切换到master分支,然后合并test分支
- git checkout master
- git merge test
这种方法相当于直接把master分支移动到test分支所在的地方,并移动HEAD指针
no-ff
如果我们不想要快速合并,那么我们可以强制指定为非快速合并,只需加上--no-ff参数
- git checkout master
- git merge –no-ff test
这种合并方法会在master分支上新建一个提交节点,从而完成合并
squash
svn的在合并分支时采用的就是这种方式,squash会在当前分支新建一个提交节点
squash和no-ff非常类似,区别只有一点不会保留对合入分支的引用
- git checkout master
- git merge –squash test
rebase
当要合并两个分叉的分支时,merge的方式是将待合入分支和当前分支不同的部分,在当前分支新建节点,如下图所示
rebase与merge不同,rebase会将合入分支上超前的节点在待合入分支上重新提交一遍,如下图,B1 B2会变为B1' B2',看起来会变成线性历史
cherry-pick
这命令简直就是神器,给你自由,你想把那个节点merge过来就把那个节点merge过来,其合入的不是分支而是提交节点
开发库、受控库和产品库
开发库、受控库和产品库是软件开发过程中配置管理里的不同类型的库,它们各自承担着不同的职能,下面为你详细介绍它们之间的区别:
定义和用途
- 开发库(动态库):开发库是供开发人员在软件开发过程中使用的工作空间。开发人员可以在开发库中自由地进行代码的编写、修改和调试。它主要用于支持开发人员的日常开发活动,允许频繁的修改和变动。
- 受控库(主库):受控库也被称为主库,是对软件项目进行版本控制和配置管理的核心库。当开发人员完成了一定阶段的开发工作,并且经过了初步的测试和审查后,会将代码和相关文档提交到受控库中。受控库用于管理软件项目的基线版本,确保项目的可追溯性和稳定性。
- 产品库(静态库):产品库是存放最终发布版本软件的地方。只有经过严格测试、审查和批准的软件版本才能进入产品库。产品库中的软件版本是稳定的,通常用于正式的发布和部署,供用户使用。
访问权限
- 开发库(动态库):开发人员对开发库具有较高的访问权限,可以自由地进行读写操作。因为开发库是他们日常工作的场所,需要频繁地进行代码的修改和调试。
- 受控库(主库):对受控库的访问权限相对严格。通常只有经过授权的人员才能对受控库进行操作,例如配置管理员、项目经理等。开发人员需要按照规定的流程进行代码的提交和变更请求,经过审批后才能将代码纳入受控库。
- 产品库(静态库):产品库的访问权限最为严格。只有少数经过授权的人员,如发布经理、质量保证人员等,才能对产品库进行操作。一般情况下,不允许对产品库中的内容进行修改,以确保发布版本的稳定性和一致性。
内容稳定性
- 开发库(动态库):开发库中的内容是不稳定的,因为开发人员在不断地进行代码的修改和调试,可能会引入各种错误和问题。开发库中的代码可能处于不完整或不一致的状态。
- 受控库(主库):受控库中的内容相对稳定。进入受控库的代码和文档都经过了一定的审查和测试,具有一定的质量保证。受控库中的版本是项目的基线版本,可以作为后续开发和维护的基础。
- 产品库(静态库):产品库中的内容是最稳定的。只有经过严格测试和验证的软件版本才能进入产品库,确保了产品的质量和可靠性。产品库中的版本通常用于正式的发布和部署,不会轻易进行修改。
变更管理
- 开发库(动态库):开发库中的变更管理相对灵活。开发人员可以根据自己的需要随时进行代码的修改和调整,不需要经过严格的审批流程。但是,为了避免冲突和混乱,开发人员通常会采用版本控制工具来管理自己的代码变更。
- 受控库(主库):受控库中的变更管理比较严格。任何对受控库的变更都需要经过正式的变更请求、审批和测试流程。变更请求需要详细说明变更的原因、内容和影响,经过相关人员的审批后才能实施。这样可以确保变更不会对项目的稳定性和可追溯性造成影响。
- 产品库(静态库):产品库中的变更管理最为严格。由于产品库中的版本是最终发布版本,任何变更都可能会对用户产生影响,因此需要经过更加严格的审批和测试流程。通常只有在发现严重的安全漏洞或影响产品正常使用的问题时,才会对产品库中的内容进行变更。
git 如何管理 开发库 受控库 产品库 通过分支吗
在 Git 中,确实可以借助分支以及相关的工作流程来管理开发库、受控库和产品库,下面详细介绍管理方法。
开发库管理
开发库是开发人员日常工作的空间,代码变动频繁。一般会用 develop
分支来模拟开发库。
- 创建开发分支:通常在项目初始时,从
master
分支创建develop
分支。
git checkout -b develop master
- 开发流程:开发人员基于
develop
分支创建自己的特性分支(feature branch)开展功能开发。
git checkout -b feature/new-feature develop
开发完成后,将特性分支合并回 develop
分支。
git checkout develop
git merge feature/new-feature
受控库管理
受控库要求代码稳定,可追溯,一般用 release
分支或者 staging
分支来模拟。
- 创建发布分支:当
develop
分支上的功能足够成熟,就从develop
分支创建release
分支。
git checkout -b release/1.0.0 develop
- 测试与修复:在
release
分支上进行测试,若发现问题就在此分支上修复。
# 修复问题
git commit -am "Fix bug in release"
- 合并到主分支与开发分支:测试通过后,把
release
分支合并到master
分支和develop
分支。
git checkout master
git merge release/1.0.0
git checkout develop
git merge release/1.0.0
产品库管理
产品库存储最终发布版本,最为稳定,一般用 master
分支来模拟。
- 发布版本:每次将
release
分支合并到master
分支时,都要打一个版本标签。
git tag v1.0.0
- 生产环境部署:
master
分支上的代码用于生产环境部署,通常只有经过严格测试和审批的代码才能进入master
分支。
示例工作流程
下面是一个完整的 Git 工作流程示例,展示如何管理这三个库:
# 初始化仓库
git init
# 创建 develop 分支
git checkout -b develop master
# 创建特性分支并开发
git checkout -b feature/new-feature develop
# 开发代码...
git commit -am "Finish new feature"
# 合并特性分支到 develop 分支
git checkout develop
git merge feature/new-feature
# 创建 release 分支
git checkout -b release/1.0.0 develop
# 测试与修复
# ...
# 合并 release 分支到 master 分支并打标签
git checkout master
git merge release/1.0.0
git tag v1.0.0
# 合并 release 分支到 develop 分支
git checkout develop
git merge release/1.0.0
# 删除 release 分支
git branch -d release/1.0.0
总结
在软件开发中,开发库(Development Library)、受控库(Controlled Library)、产品库(Product Library) 是配置管理的核心概念,通常对应代码的不同生命周期阶段。以下是基于 Git 的典型管理实践:
1. 开发库(Development Library)
用途:日常开发环境,存储正在开发中的代码。
管理方式:
- 分支策略:
- 主分支(如
main
/master
)仅作为稳定基线,不直接开发。 - 开发分支(如
develop
)作为默认开发分支,或按功能拆分feature/*
分支。 - 鼓励短期分支(如
feature/login
)进行开发,完成后合并到develop
。
- 主分支(如
- 权限:
- 开发者可自由推送代码到
develop
或个人分支。 - 通过代码审查(如 GitHub PR/GitLab MR)控制合并质量。
- 开发者可自由推送代码到
- 自动化:
- 集成 CI/CD 流水线,自动运行单元测试、代码检查。
2. 受控库(Controlled Library)
用途:存储通过测试、待发布的稳定版本,需严格管控变更。
管理方式:
- 分支策略:
- 使用
release/*
分支管理预发布版本(如release/1.2.0
)。 - 发布前在此分支修复 Bug,合并到
develop
和main
。 - 通过 Git Tag(如
v1.2.0
)标记正式版本。
- 使用
- 权限:
- 仅限管理员或指定角色合并代码到
release/*
分支。 - 推送需触发自动化测试和审批流程。
- 仅限管理员或指定角色合并代码到
- 流程:
- 从
develop
创建release/*
分支。 - 修复 Bug 并验证。
- 合并到
main
(打 Tag)和develop
。
- 从
3. 产品库(Product Library)
用途:存储已发布的正式产品代码,需完全受控且不可修改。
管理方式:
- 分支策略:
main
分支作为产品库主干,仅通过合并release/*
或hotfix/*
分支更新。- 每个正式版本通过 Git Tag(如
v1.2.0
)唯一标识。
- 权限:
- 仅允许管理员推送代码到
main
或创建 Tag。 - 禁止直接修改历史提交(可通过
git push --force-with-lease
限制)。
- 仅允许管理员推送代码到
- 流程:
- 发布时从
main
打 Tag。 - 通过自动化部署工具(如 Jenkins、GitHub Actions)将 Tag 部署到生产环境。
- 发布时从
典型 Git 工作流整合
推荐使用 Git Flow 或 GitHub Flow 扩展模型:
- Git Flow:
develop
:开发库。release/*
:受控库分支。main
:产品库主干。hotfix/*
:紧急修复分支。
- GitHub Flow(简化版):
- 所有开发在
main
分支进行,通过 PR 合并。 - 发布时直接从
main
打 Tag,省略develop
分支。
- 所有开发在
工具与权限控制
- Git 钩子(Hooks):
- 预推送钩子(
pre-push
)检查分支名称、代码规范。 - 更新钩子(
post-update
)触发自动化流程。
- 预推送钩子(
- 代码托管平台:
- GitHub/GitLab:通过分支保护规则(Protected Branches)限制推送权限。
- 合并请求(MR/PR)需通过代码审查和 CI 测试。
- 权限矩阵:
- 开发人员:读写
develop
、feature/*
分支。 - 管理员:读写
main
、release/*
分支。 - 只读权限:外部用户或测试环境。
- 开发人员:读写
总结实践
- 开发库:灵活开发,通过分支隔离变更。
- 受控库:严格测试和审批流程,确保稳定性。
- 产品库:不可变历史,通过 Tag 标识发布版本。
- 自动化:CI/CD 贯穿全流程,减少人为错误。
通过结合分支策略、权限控制和自动化工具,可实现高效且安全的代码管理流程。