有两个程序员,老板现在让写一个产品,写完后老板觉得不满意,让修改一下,笨的程序员
会直接在原产品上直接去修改,而聪明的程序员
会复制一个副本出来在副本上去修改,然后处理完后老板还是不满意,又加需求,两位程序员继续之前的工作方法,在加了五次需求后,老板说还是第一版比较好,用第一版吧,这个时候笨的程序员就傻了,因为已经没有最初的版了,然后聪明的程序员觉得,既然已经决定用最初的了,其他的就删了吧,然后第二天老板说客户对第三版比较满意,我们用第三版吧,这时聪明的程序员和笨的程序员都傻了。
然后来了个更聪明的程序员
,他会用git,他在本地创建了一个版本库,每次老板让他修改的时候,他就把之前的版本提交,并标明这版的主要特点是什么,这样文件夹里就只有一个文档,每次老板说要那个版本的,他就直接从版本库里恢复一下。
通过人工的复制行为来保存项目的不同阶段的内容,添加适当的一些描述文字加以区分——上述的聪明的程序员的做法
通过程序完成上述人工版本控制行为——上述的更聪明的程序员的做法
首先我们需要了解两个重要的概念
git提供了三种(也可以说是四种)不同的记录状态
有一种特殊的状态
git提供了三个不同的工作区,用来存放不同的内容
https://npm.taobao.org/mirrors/git-for-windows/
当安装完Git你应该做的第一件事就是设置你的用户名称与邮件地址,哪怕你第一件事不是设置用户名与邮箱地址,也会在后续的操作中弹出让你设置,因为每一个Git的提交都会使用这些信息,并且它会写入到你的没一次提交中,不可更改
git config user.name "你的姓名"
git config user.email "你的邮箱"
通过 --global
选项可以设置全局配置信息
git config --global user.name "你的姓名"
git config --global user.email "你的邮箱"
# 打印所有config
git config --list
# 打印指定config
git config user.name
进去你要创建git的版本控制的目录内,使用git init
初始化一个仓库
git init
该命令将创建一个名为 .git
的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这个目录也是上面我们说的三个区域之一,这个目录也是 Git 保存数据记录的地方,非常重要,如非必要,不要轻易改动
当一个项目被 Git 初始化以后,只是表示我们希望通过 Git 来管理当前的这个项目文件的不同时期版本记录,但是这个时候项目中已存在的文件,或者以后新增的文件都是没有进入版本控制管理的,它们是 未追踪(Untracked)
的状态
git status
git status
查看工作区中的文件状态
git config --global core.quotepath false
菜单 -> 设置 -> 文本 -> 本地 / 编码
或修改配置文件
[gui]
encoding = utf-8
# 代码库统一使用utf-8
[i18n]
commitencoding = utf-8
# log编码
[svn]
pathnameencoding = utf-8
# 支持中文路径
[core]
quotepath = false
# status引用路径不再是八进制(反过来说就是允许显示中文了)
git add
git add 1.txt
# 添加多个文件
git add 2.txt 3.txt
# 添加整个目录
git add ./a
# 添加多个目录
git add ./b ./c
# 添加所有文件
git add .
git commit
将暂存区里的改动给提交到本地 git 仓库,也就是为这次工作(一般会把某个具有特定意义的工作作为一个版本,它可以是多个文件的变化)
每次提交都需要填写备注信息
git commit (如果只提交一个文件的话需要加上文件名)
# 会调用默认(或自定义)的文本编辑器
git config core.editor notepad
# 添加 vscode 编辑器 - mac
# 通过 vim 打开环境变量配置文件
vim ~/.bash_profile
# 添加环境变量
export PATH=/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin:$PATH
# 保存退出
source ~/.bash_profile
# 测试:在终端中直接通过命令 code 调用 vscode
git config --global core.editor "code --wait"
git commit (如果只提交一个文件的话需要加上文件名) -m 备注信息
使用cmd时,这里的备注信息是英文的话,注意不要加空格,使用驼峰命名法
git log
// 完整格式
git log
// 简要格式(单行)
git log --oneline
git commit --amend
修复(替换上一次)提交,在不增加一个新的提交版本的情况下将新修改的代码追加到前一次的提交中
git commit (如果只提交一个文件的话需要加上文件名) --amend -m 提交
git rm
# 从 git 仓库与工作区中删除指定文件
git rm 文件
# 只删除 git 仓库中的文件
git rm --cached 文件
# rm 以后,需要 commit 这次操作,否则 rm 将保留在暂存区
git commit -m 修正
git reset
// 从暂存区中撤销一个指定文件
git reset HEAD 文件名称
// 从暂存区中撤销所有文件
git reset HEAD .
# 回退到指定的 commitID 版本
git reset --hard commitID
# 比较 工作区和暂存区
git diff 文件
# 比较 暂存区和仓库
git diff --cached [commitId] 文件
# 比较 工作区和仓库
git diff commitId filename
# 比较 仓库不同版本
git diff commitId1 commitId2
我们再开发的时候就像是游戏任务,默认是在主线上进行开发的,但许多时候,还会有各种支线人物,git支持我们创建分支来进行项目开发
就一个例子,我们现在一个团队,开发了半年的一个项目,报了一个错误,这时候直接在原项目上改的时候可能会出一些其他方面的报错,更严重的会导致崩盘整个项目炸裂,那这个时候造成的损失时不可预估的,最稳妥的方式就是创建一个原项目的副本,在副本上做修改,哪怕副本崩盘,大不了删除在创建一个副本罢了。git提供的分支就类似于我们创建一个新的副本
git branch
git branch 分支名称
git checkout 分支名称
# 也可以使用 checkout -b 来新建分支
git checkout -b 分支名称
# B 合并到 A,需要切换到 A 分支
git merge 被合并分支
# 查看已经合并的分支
git branch --merged
# 查看未合并的分支
git branch --no-merged
# 如果分支为未合并状态,则不允许删除
git branch -d 分支名称
# 强制删除
git branch -D 分支名称
rebase
# 合并 HEAD 前两个祖先记录
git rebase -i HEAD~2
~ : 纵向
# p, pick = use commit => 使用
# r, reword = use commit, but edit the commit message => 使用,但重新编辑说明
# e, edit = use commit, but stop for amending => 使用
# s, squash = use commit, but meld into previous commit => 使用,但合并上一次
# f, fixup = like "squash", but discard this commit's log message => 就像 squash 那样,但会抛弃这个 Commit 的 Commit message
# x, exec = run command (the rest of the line) using shell => 执行脚本
# d, drop = remove commit => 移除
git rebase -i HEAD~3
# 弹出编辑器,根据需要的进行修改,然后保存
# 如果为 r,s 则会再次弹出编辑器,修改新的 commit message,修改之后保存
如果出现一些问题,可以通过
git rebase --edit-todo
和git rebase --continue
进行重新编辑保存
有的时候,不同的分支可能会对同一个文件内容和位置上进行操作,这样在合并的过程中就会产生冲突
有的时候,我们希望给某一个特定的历史提交打上一些标签
git tag -a v1.0.0 HEAD/commitId
git tag