一篇文章,教你学会Git

390 阅读13分钟

说起代码管理方式,就会想起我们常用的Git,svn。git是分布式的管理方式,svn是集中式的管理方式。大部分公司都在用git来管理代码,一起git命令来管理代码吧。

Linus在1991年创建了开源的Linux。(请不要傻傻分不清Linus和Linux)

当时Linus选择了一个商业的版本控制系统BitKeeper(商业版本控制系统),由于某种原因BitKeeper的公司不让他们使用了。

Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!

前几年,git操作发生的严重问题:

马蜂窝的前端火了!遇到冲突不怕怼,强制提交就是干

当两条分支对同一个文件的同一个文本块进行了不同的修改,并试图合并时,Git不能自动合并的,称之为冲突(conflict)。解决冲突需要人工处理。

思维导图:git 代码管理

思维导图:常用git命令

一、代码管理 — Git基础

1、Git的产生

Linus在1991年创建了开源的Linux。(请不要傻傻分不清Linus和Linux)

当时Linus选择了一个商业的版本控制系统BitKeeper(商业版本控制系统),由于某种原因BitKeeper的公司不让他们使用了。Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!

Git显著优点就是版本的分支(branch)和合并(merge)十分方便。(重要)

github主要提供基于git的版本托管服务

git下载:git-scm.com/downloads/

2、Git工作原理

1、Workspace:工作区,执行git add *命令就把改动提交到了暂存区,执行git pull命令将远程仓库的数据拉到当前分支并合并,执行git checkout [branch-name]切换分支。

2、Index:暂存区,执行git commit -m '说明' 命令就把改动提交到了仓库区(当前分支)。

3、Repository:仓库区(或本地仓库),执行git push origin master提交到远程仓库,执行git clone 地址将克隆远程仓库到本地。

4、Remote:远程仓库,就是类似github,coding等网站所提供的仓库。

*扩展知识:

git的常规流程

1、每一个git仓库都有三个区:

工作区:写代码

暂存区:临时存放每一次修改的代码,但是并没有生成历史版本

历史区:存放所有历史版本的地方(提交到历史区就会生成历史版本)

2、把暂存区的某一个文件删除(提交到暂存区的内容不好,我们可以删除)

git rm --cached xxx.xxx

git rm --cached . -r 删除暂存区中所有提交的

说明:如果在删除过程中,发现从暂存区删除的文件,在工作区已经被修改了,只有加上 -f 才能强制从暂存区把内容删除掉。

3、提交到暂存区一份,把工作区内容改了,但是改的东西不好,想把暂存区上次提交的内容撤回到工作区(覆盖工作区新写的内容)(常用)

git checkout xxx.xxx
说明:暂存区内容没有消失,只是把工作去最新修改的信息给覆盖了,让工作区和暂存区保持一致。

*工作区、暂存区、历史区关系说明:

1、git add -A/.

把当前工作区修改为内容全部提交到暂存区(可以指写具体提交的文件 git add xxx.js)。

2、git commit -m "[备注]"

把暂存区中的内容提交到历史区,生成一个历史版本(我们需要写备注信息,声明当前版本的特点)。

说明:

每一次区域间信息的提交都不会删除原有区域中的内宾,这样保证,下一次提交,只是把区域对比出来不一样的内容提交,只是把区域对比出来不一样的内容提交,而不是所有。

3、git status 查看当前修改的文件

处于哪一个区域:1)红色:工作区 2)绿色:暂存区 3)看不见:已经提交到历史区,三区保持一致了。

*说明:.git 文件包含暂存区与历史区内容 (重要)

二、代码管理 — git flow 流程

1、项目分支

项目存在两个长期分支

主分支master:对外发布的版本,任何时候在这个分支拿到的,都是稳定的分布版;

开发分支develop:用于日常开发,存放最新的开发版。

项目存在三种短期分支

功能分支 feature branch: feature分支都是基于develop创建的,开发完成后会合并到develop分支上。

预发分支 release branch:基于最新develop分支创建,当新功能足够发布一个新版本。

补丁分支 hotfix branch:基于master分支创建,对线上版本的bug进行修复。

2、多人开发注意点:

1、今日代码今日提交,保证正常;

2、功能点建项目分支;

3、git commit 注释明确;

4、git rebase(基线)

三、代码管理 — Git与svn区别

1、git分布式版本控制

优点:1) 本地提交,在本地可以提交,创建分支,代码回滚。2) 每台开发机都是完整的仓库,便于恢复。

缺点:1) 缺乏对文件的权限控制。2) 学习相对复杂。

git commit 不需要网络,git push需要联网

git流程图

2、svn集中式版本控制

优点:1) 权限精细管理。2) 统一管理,概念简单

缺点:1) 中央服务器宕机机,则无法提交代码。2) 中央服务器故障会引起无法提交乃至历史记录全部丢失。

集中式版本控制系统最大的毛病就是必须联网才能工作

svn流程图

重要说明:

1、git是按照源数据(文件流)来实现文件传输的,而svn是按照文件传输的,所有git比svn更快。

2、linux团队开发的git,所以git中的命令大部分都是linux命令。

四、代码管理 - 常用git命令

*项目实践

**(**fork项目,将别人的仓库复制一份到自己的仓库)

操作流程:

# 切换develop分支

git checkout develop

# 改下远程仓库push地址-添加命令

git remote add admin-jsx github.com/jiasx/frame…

# 查看现有远程仓库的地址url

git remote -v

# 本地与开发建立关系 (同步)

git pull admin-jsx develop

代码分支同步

git fetch admin-jsx develop-market:develop-market

*撤销代码(重要)

# 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变;

git reset [file]

# 后者的所有变化都将被前者抵消,并且应用到当前分支;

git revert [commit]

**说明:**撤销(revert)被设计为撤销公开的提交的安全方式,git reset被设计为重设本地更改。

区别:

  1. git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit

  2. git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容

  3. 在回滚这一操作上看,效果差不多。但是在日后继续 merge 以前的老版本时有区别

*git fetch 和git pull 的差别(重要)

  1. git fetch 相当于是从远程获取最新到本地,不会自动merge

  2. git pull:相当于是从远程获取最新版本并merge到本地

注:git pull是git fetch和git merge两个步骤的结合。

新建代码库

# 在当前目录新建一个Git代码库

$ git init

# 新建一个目录,将其初始化为Git代码库

$ git init [project-name]

# 下载一个项目和它的整个代码历史

$ git clone [url]

初始化配置

# 设置提交代码时的用户信息

$ git config --global user.name "yourname" // 设置用户名

$ git config --global user.email myemail@qq.com // 设置用户邮箱

# 编辑Git配置文件

$ git config -e [--global]

# 显示当前的Git配置

$ git config --list // 查看git设置列表信息

本地分支修改操作:

1、git checkout . #本地所有修改回到原来的状态

2、$ git checkout -- app/index.html #本地个别修改恢复。

命令行窗口没有关掉时(时光穿梭)

git log 查看历史

git reflog 查看命令历史,以便确定要回到未来的哪个版本。

恢复上一个版本 ( git reflog )

git reset --hard 3628164

存储操作(保存改动)

git stash 删除并保存改动

git stash pop 恢复代码

git stash list 查看所有存储中的工作

git stash clear 清空所有存储的工作

修正提交最后一个 commit 消息

git commit --amend 或 git commit --amend -m "Fixes bug #42"

提交master后,如何处理

git push -f 命令去强制提交 (强行推送到远端)(不建议使用)

注:如果已经提交master分支,建议本地分支进行修改,重新提交。

删除远程分支

git fetch -p 本地删除远程已经删除的分支显示

git branch -a 用来查看远程分支

git push origin :feature/construction 删除远程分支

改下远程仓库push地址

git remote -v 查看现有远程仓库的地址url

1. 修改命令

git remote set-url origin 更换远程仓库地址。把更换为新的url地址。

2、添加命令

git remote add jt github.com/TheChalice/…

Git仓库完整迁移 (注:新的git地址,需要建个分支)

1. 随便找个文件夹,从原地址克隆一份裸版本库

git clone --bare 旧的git地址

2. 推送裸版本库到新的地址

cd xxx.git git push --mirror 新的git地址

Git鼓励大量使用分支

查看分支:git branch

创建分支:git branch

切换分支:git checkout

创建+切换分支:git checkout -b

合并某分支到当前分支:git merge

删除分支:git branch -d

取消一个目录的git初始化

执行rm -rf .git

查看详细的commit信息

git show 2e21737

关于提交信息的格式,可以遵循以下的规则:

feat: 新特性,添加功能

fix: 修改 bug

refactor: 代码重构

docs: 文档修改

style: 代码格式修改, 注意不是 css 修改

test: 测试用例修改

chore: 其他修改, 比如构建流程, 依赖管理

五、git rebase和git merge

简单的说,git merge和git rebase都是合并分支的命令。

rebase 的概念/作用其实很简单——就是「变基」。具体来说,就是改变一条分支的「基点」,使原分支从指定的地方(commit)重新长出来。rebase 可以保证commit为一条线。

**merge优点:**保留有价值的历史文档,merge缺点:分支杂乱冗余。

**rebase优点:**删减就繁,rebase缺点:无法体现时间线。

git rebase的作用: 提交记录就不会出现分叉,保持了提交记录的整洁。

说明:

如果项目庞大,需要一个简洁的线性历史树便于leader管理,推荐使用 git rebase 。

如果是小型项目,需要审查历史纪录来便于编写过程报告,则推荐使用 git merge 。

区别

从上面可以看到,merge和rebasea都是合并历史记录,但是各自特性不同:

1) merge

通过merge合并分支会新增一个merge commit,然后将两个分支的历史联系起来。

其实是一种非破坏性的操作,对现有分支不会以任何方式被更改,但是会导致历史记录相对复杂。

2) rebase

rebase会将整个分支移动到另一个分支上,有效地整合了所有分支上的提交。

主要的好处是历史记录更加清晰,是在原有提交的基础上将差异内容反映进去,消除了 git merge所需的不必要的合并提交。

注:git log --graph 提交记录的顺序问题

六、代码管理 - 开发上线流程

七、代码管理 - 遇到的坑

*出现冲突的场景有如下:

  1. 多个分支修改了同一个文件(任何地方)或者多个分支修改了同一个文件的名称。

  2. 如果两个分支中分别修改了不同文件中的部分,是不会产生冲突,直接合并即可。

git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容:

<<<<<<< 和 ======= 之间的区域就是当前更改的内容

======= 和 >>>>>>> 之间的区域就是传入进来更改的内容

代码冲突原因:两个人同时修改同一个文件,提交就会报冲突的错误。

解决冲突方法:

1、建议在代码提交之前先git merge develop 与develop进行同步。(减少冲突)

2、如果merge不成功,说明你的代码与别人的代码冲突了。需要怎么搞呢?

1)首先git status 查看本地代码修改情况。

2)通过以下命令,删除与恢复代码。

git stash 删除并保存改动

git stash pop 恢复改动

注:用这个操作,一般都处理 merge不成功的问题。

3、git push -f 命令去强制提交 (强行推送到远端)(不建议使用)

4、git 报错 gitThere is no tracking information for the current branch.

是因为本地分支和远程分支没有建立联系

git branch --set-upstream-to=origin/远程分支的名字 本地分支的名字。

远程服务端的用户名和密码与当前系统中git保存的用户名和密码有冲突

解决remote: HTTP Basic: Access denied

1、从GitLab中克隆项目时,报“git remote: HTTP Basic: Access denied ”错误;

远程服务端的用户名和密码与当前系统中git保存的用户名和密码有冲突。

2、当git输入密码错误时,git某版本未提供再次输入账户密码的提示框。

解决办法

打开控制面板=>用户账户和家庭管理=>管理Windows凭据=>普通凭据里找出重新编辑账号密码即可

八、代码管理 — 忽略特定的文件

可以配置Git忽略特定的文件或者是文件夹。这些配置都放在.gitignore文件中。

下面我们看看常用的规则:

1)node_modules/ 过滤整个文件夹

2)*.zip 过滤所有.zip文件

3)/mtk/do.c 过滤某个具体文件

九、代码管理 — 针对初学者的建议

对于git操作不熟悉的同学,建议自己搭个github工程,这样就可以随便玩git命令了。

坑越大,进步就越大。我也是刚从大坑爬出来的。一起git起来。

十、常用的LINUX命令

我们更多的都是基于命令来完成git管理的,所以我们学一些简单的linux命令。

windows操作系统:DOS窗口和DOS命令;

linux服务器操作系统:linux命令 (mac的终端使用的也是linux命令);

常用命令如下:

1、ls -l/-a:查看当前目录结构(-a是可以看见所有的:包含隐藏的)。

2、cd XXX [路径地址]:进入到执行的文件夹中(进入的路径地址,可以粘贴到对应的操作命令窗口中)

cd /:根目录

cd ./:当前目录

cd ../:上级目录

3、clear:清屏

4、mkdir:创建文件夹

5、touch:创建空的文件

6、vi:向文件中插入或者管理一些内容

i => 进入到插入模式

esc + :wq ,退出内容的插入模式,把刚才编辑的内容进行保存;

7、echo:向指定的文件中输入内容

8、cat:查看文件中的内容

9、rm:删除文件或者文件夹 -r (递归删除) -f (强制删除),一旦删除无法还原;

10、cp 拷贝

11、exit 退出

🌰 例如:

删除node_modules文件夹 wq保存并退出

rm -rf node_modules/ ( shift+:) esc定位当前位置