This repository has been archived on 2023-11-13. You can view files and clone it, but cannot push or open issues or pull requests.
blog/_posts/2022-04-06-git.md
2023-06-03 15:58:09 +08:00

14 KiB
Raw Blame History

layout, title, subtitle, date, author, catalog, header-img, tags
layout title subtitle date author catalog header-img tags
post Git应用简记 Awesome version control tool 2022-04-06 15:37:35 Manford Fan false img/post-bg-universe.jpg
Git
Tools

如果你知道Linux那你一定知道Linus TorvaldsGit正是这位传奇天才的第二个杰作。关于Git有人说是Linus为了开发Linux Kernel的兄弟们不被人拿捏。事情发生在2005年4月Andrew Tridgell 为了开发一个可以与BitKeeper交互的工具试图反编译BitKeeper。这让开发该软件的公司BitMover得知并取消了Linux社区免费试用BitKeeper的权利。这也成为了Linus开发Git的契机促进了Git这一伟大作品的诞生。关于Git的全部使用方法大概可以写好几本书了这里仅就环境的配置以及基本的使用做一些记录剩下的使用可以参考官方文档

一、GIT简介 -- From book 《Pro Git》

1. Git简史

同生活中的许多伟大事物一样Git诞生于一个极富纷争大举创新的年代。Linux内核开源项目有着为数众多的参与者。 绝大多数的Linux内核维护工作都花在了提交补丁和保存归档的繁琐事务上19912002年间。到2002年整个项目组开始启用一个专有的分布式版本控制系统BitKeeper来管理和维护代码。到了2005年开发BitKeeper的商业公司同Linux内核开源社区的合作关系结束他们收回了Linux内核社区免费使用BitKeeper的权力。 这就迫使Linux开源社区特别是Linux的缔造者Linus Torvalds基于使用BitKeeper 时的经验教训,开发出自己的版本系统。他们对新的系统制订了若干目标:

  • 速度
  • 简单的设计
  • 对非线性开发模式的强力支持(允许成千上万个并行开发的分支)
  • 完全分布式
  • 有能力高效管理类似Linux内核一样的超大规模项目速度和数据量

自诞生于2005年以来Git日臻成熟完善在高度易用的同时仍然保留着初期设定的目标。 它的速度飞快极其适合管理大项目有着令人难以置信的非线性分支管理系统参见Git分支

2. Git 是什么?

那么简单地说Git究竟是怎样的一个系统呢 请注意接下来的内容非常重要,若你理解了 Git 的思想和基本工作原理,用起来就会知其所以然,游刃有余。 在学习 Git 时,请尽量理清你对其它版本管理系统已有的认识,如 CVS、Subversion 或 Perforce 这样能帮助你使用工具时避免发生混淆。尽管 Git 用起来与其它的版本控制系统非常相似, 但它在对信息的存储和认知方式上却有很大差异,理解这些差异将有助于避免使用中的困惑。

直接记录快照,而非差异比较

Git和其它版本控制系统包括Subversion和近似工具的主要差别在于Git对待数据的方式。从概念上来说其它大部分系统以文件变更列表的方式存储信息这类系统CVS、Subversion、Perforce、Bazaar等等 将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异——它们通常称作 基于差异[delta-based]的版本控制。

git_snapshoot

二、Windows/Linux平台配置

再进一步记录git的使用方法之前首先需要配置一个可用的最小化环境。以Windows和Linux平台为例这两个平台配置方法几乎完全一样只是在配置路径的时候稍有差别。

  1. 安装git
  • [Windows]下载最新版git安装包并双击安装
  • [Linux]用软件包管理工具进行安装,apt install git
  1. 配置用户名和邮箱
  • git config --global user.name 'xxx'
  • git config --global user.email 'xxx@yyy'
  1. 配置ssh密钥
  • 方法1git config --global core.sshCommand "ssh -i 'path/to/your/key'"
  • 方法2编辑如下内容保存为config文件放在.ssh目录下注意修改第四行
Host github.com
HostName github.com
User mffan0922
IdentityFile path/to/your/key
AddKeysToAgent yes 
PreferredAuthentications publickey
Port 22

另外涉及到多个平台配置,或者多用户配置的时候,一般不使用--global选项,而是在对应项目下使用--local选项,设定用户名和邮箱,设定之前需要使用--unset删除全局配置。其实不删除也可以,因为--local的优先级比--global的优先级高。

三、Git的基本工作原理

Git是由三个如果包括远程仓库那就是四个区域组成分别是工作区暂存区和本地仓库对应的状态有(un)tracked/modified/staged/committedGit更像是把数据看作是对小型文件系统的一系列快照。在Git中每当你提交更新或保存项目状态时它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。为了效率如果文件没有修改Git不再重新存储该文件而是只保留一个链接指向之前存储的文件。Git对待数据更像是一个快照流

git_three_area

四、Git常用命令

git命令支持的选项非常之多,对应于研发人员的各种需求;一般使用者不需要了解这么多,只要掌握基础的用法就足够了。如果想了解更多命令的详细用法,可以使用git cmd --help的方式来获取,cmd代表git支持的各种子命令。另外git也非常贴心,再执行每一步的时候都会给出近乎于啰嗦的指导。使用git --help会输出如下简要的帮助信息:

usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone             Clone a repository into a new directory
   init              Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add               Add file contents to the index
   mv                Move or rename a file, a directory, or a symlink
   restore           Restore working tree files
   rm                Remove files from the working tree and from the index
   sparse-checkout   Initialize and modify the sparse-checkout

examine the history and state (see also: git help revisions)
   bisect            Use binary search to find the commit that introduced a bug
   diff              Show changes between commits, commit and working tree, etc
   grep              Print lines matching a pattern
   log               Show commit logs
   show              Show various types of objects
   status            Show the working tree status

grow, mark and tweak your common history
   branch            List, create, or delete branches
   commit            Record changes to the repository
   merge             Join two or more development histories together
   rebase            Reapply commits on top of another base tip
   reset             Reset current HEAD to the specified state
   switch            Switch branches
   tag               Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch             Download objects and refs from another repository
   pull              Fetch from and integrate with another repository or a local branch
   push              Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.

这里采用解决问题的方式来记录,使用git的基本命令,但是单纯的记录每个命令的用法,因为该命令的子命令太多了,在使用场景下会更容易理解其原理,掌握了基础用法之后,在遇到其他问题时,也可以很自然的扩充。

1 工作的最小化配置 - [config]

Git安装好之后需要使用git config命令来做一些基本的配置其中包括让Git正常运行的用户名和邮箱配置。

git config --global user.name "[firstname lastname]"  # 设置全局用户
git config --global user.email "[valid-email]"        # 设置对应邮箱

config命令支持system/global/local三种层级,系统级是针对服务器所有用户生效,配置文件一般记录在/etc/gitconfig文件;全局配置是针对当前用户所有仓库生效,一般记录在/userDir/.gitconfig文件;而本地级则只对当前文件夹对应的仓库生效,一般记录在.git/config文件,三者的优先级是依次升高的,。该命令其他常用用法汇总如下:

git config --list            		 	# 列出当前repo的配置
git config --global --list   		 	# 列出全局repo的配置
git config --global color.ui auto    	# 设置git彩色输出
git config --global core.editor vim  	# 设置默认编辑器
git config --global --unset user.name	# 删除global层级的user.name配置
git config --global init.defaultBranch main # 将默认分支名称修改为main

2.1 创建一个Git管理仓库 - [init]

这里有两种情景一种是创建一个空的Git仓库另一种是已经有了个项目现在要将其纳入Git管理

创建空仓库

# Method One ==========================
mkdir git_learning
cd git_learning
git init

# Method Two ==========================
git init git_learning

管理已有项目

cd project
git init
git add -A
git commit -m '[add] initial commit'

git add命令是Git最常用的命令之一其作用是将文件从工作区转移到暂存区以等待后续提交到仓库如下是该命令的其他常用参数

git add -u					# 将已纳入管理且已修改的文件,放置到暂存区
git add -A					# 将所有已修改文件包括untracked文件全部放置到暂存区
git add -f fileA			# 将fileA(即使已经被忽略)放置到暂存区

2.2 从远程仓库下载 - [clone]

clone指令是从远程将仓库下载(克隆)下来,一般情况默认将仓库所有的信息都会下载下来。执行完git clone命令后当前目前称为目录A目录A下 并没有形成本地仓库命令执行结束之后目录A下会多一个目录B目录B下就是本地git仓库并且本地git仓库已经和远程git仓库连接。此时本地仓库默认分支名字是main因为当前远程仓库的默认分支名字是main。本地仓库关联的远程仓库当前默认名字是origin。

git clone git@github.com:manerfan/vuesume.git      # 使用ssh协议从远程clone下来需要配置密钥
git clone https://github.com/manerfan/vuesume.git  # 使用https协议冲远程clone下来
git clone https://github.com/manerfan/vuesume.git rename-to-git # 将克隆的仓库下载到本地并重命名为rename-to-git
git clone -b dev https://github.com/manerfan/vuesume.git # 自动将dev分支配置为本地分支
git clone --bare git@github.com:manerfan/vuesume.git # 创建一个裸仓库后续需要手动checkout

3. 本地项目和远程仓库关联 - [remote]

理想的情况下是在远程创建好仓库,使用git clone命令下载到本地,然后在本地添加新的项目文件,并push到远程,这种情况下基本不会出现什么问题;还有一种情况是本地已经有项目文件了,这时就需要手动关联本地和远程仓库,必要的话手动解决文件冲突,并提交到远程。

cd local_prj
git init
git add -A
git commit -m '[add] initial commit'
git remote add origin git@github.com:manerfan/vuesume.git
git pull origin main --allow-unrelated-histories
# 手动解决冲突
git push -u origin main

4. 分支相关 - [branch]

几乎每一种版本控制系统都以某种形式支持分支一个分支代表一条独立的开发线。使用分支意味着你可以从开发主线上分离开来然后在不影响主线的同时继续工作。Git 分支实际上是指向更改快照的指针。有人把Git的分支模型称为必杀技特性而正是因为它将Git从版本控制系统家族里区分出来。

git branch -av                   # 查看所有分支
git branch new-branch            # 基于当前分支,新建分支
git checkout new-branch          # 切换到新分支
git checkout -b new-branch       # 基于当前分支,新建分支,并切换到新分支
git branch -d deleted-branch     # 将分支删除
git push origin --delete deleted-branch # 将远程分支删除
git merge dev                    # 将dev分支合并到当前分支
git branch --set-upstream-to=origin/main # 将当前分支设定跟踪远程分支

5. git三部曲 - [add/commit/push]

所谓Git三部曲指的是从添加一个文件纳入到Git管理放置到暂存区提交到本地仓库最后同步到远程仓库的过程。

git add *                        # 添加所有文件,包括未跟踪和已修改,但不包括隐藏文件
git add -A                       # 添加所有文件,包括未跟踪和已修改和隐藏文件
git add .                        # 同 git add -A
git commit -m '[add/modify] something to say'         # 提交到本地仓库,并添加注释
git commit -a -m '[add/modify] something to say'      # 将所有已变更文件,提交到本地仓库,并添加注释
git commit --amend -m '[add/modify] something to say' # 对于同一个文件多次修改后提交生成一个commit id
git push origin main             # 推送到远程

至于如何撤销变更以及提交等在操作Git的时候会给出相应的提示再有比较进阶的用法例如如何变更已经提交的内容如何整理已经提交的commit id甚至合并分支时需要注意的事项等等后续用到的时候在做补充。

五、参考文档