Git教程

Git教程

参考文档:
菜鸟教程
廖雪峰官网
易百教程

简介

Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。

安装配置

Git 目前支持 Linux/Unix、Solaris、Mac和 Windows 平台上运行。Git 各平台安装包下载地址为:http://git-scm.com/downloads。

1、安装

a、Linux 平台上安装

Git 的工作需要调用 curl,zlib,openssl,expat,libiconv 等库的代码,所以需要先安装这些依赖工具。

在有 yum 的系统上(比如 Fedora)或者有 apt-get 的系统上(比如 Debian 体系),可以用下面的命令安装:

各 Linux 系统可以使用其安装包管理工具(apt-get、yum 等)进行安装:

Debian/Ubuntu

Debian/Ubuntu Git 安装命令为:

$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \
  libz-dev libssl-dev

$ apt-get install git

$ git --version
git version 1.8.1.2
Centos/RedHat

如果你使用的系统是 Centos/RedHat 安装命令为:

$ yum install curl-devel expat-devel gettext-devel \
  openssl-devel zlib-devel

$ yum -y install git-core

$ git --version
git version 1.7.1
源码安装

我们也可以在官网下载源码包来安装,最新源码包下载地址:https://git-scm.com/download

安装指定系统的依赖包:

########## Centos/RedHat ##########
$ yum install curl-devel expat-devel gettext-devel \
  openssl-devel zlib-devel

########## Debian/Ubuntu ##########
$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \
  libz-dev libssl-dev

解压安装下载的源码包:

$ tar -zxf git-1.7.2.2.tar.gz
$ cd git-1.7.2.2
$ make prefix=/usr/local all
$ sudo make prefix=/usr/local install

b、Windows 平台上安装

在 Windows 平台上安装 Git 同样轻松,有个叫做 msysGit 的项目提供了安装包,可以到 GitHub 的页面上下载 exe 安装文件并运行:

安装包下载地址:https://gitforwindows.org/

官网慢,可以用国内的镜像:https://npm.taobao.org/mirrors/git-for-windows/。

完成安装之后,就可以使用命令行的 git 工具(已经自带了 ssh 客户端)了,另外还有一个图形界面的 Git 项目管理工具。

在开始菜单里找到"Git"->"Git Bash",会弹出 Git 命令窗口,你可以在该窗口进行 Git 操作。


c、Mac 平台上安装

在 Mac 平台上安装 Git 最容易的当属使用图形化的 Git 安装工具,下载地址为:

http://sourceforge.net/projects/git-osx-installer/

安装界面如下所示:

18333fig0107-tn


Git 配置

Git 提供了一个叫做 git config 的工具,专门用来配置或读取相应的工作环境变量。

这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:

  • /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。
  • ~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。
  • 当前项目的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。

在 Windows 系统上,Git 会找寻用户主目录下的 .gitconfig 文件。主目录即 $HOME 变量指定的目录,一般都是 C:\Documents and Settings$USER。

此外,Git 还会尝试找寻 /etc/gitconfig 文件,只不过看当初 Git 装在什么目录,就以此作为根目录来定位。

用户信息

配置个人的用户名称和电子邮件地址:

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

如果用了 --global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。

如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。

文本编辑器

设置Git默认使用的文本编辑器, 一般可能会是 Vi 或者 Vim。如果你有其他偏好,比如 Emacs 的话,可以重新设置:

$ git config --global core.editor emacs

差异分析工具

还有一个比较常用的是,在解决合并冲突时使用哪种差异分析工具。比如要改用 vimdiff 的话:

$ git config --global merge.tool vimdiff

Git 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等合并工具的输出信息。

当然,你也可以指定使用自己开发的工具,具体怎么做可以参阅第七章。

查看配置信息

要检查已有的配置信息,可以使用 git config --list 命令:

$ git config --list
http.postbuffer=2M
user.name=runoob
user.email=test@runoob.com

有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。

这些配置我们也可以在 ~/.gitconfig/etc/gitconfig 看到,如下所示:

vim ~/.gitconfig 

显示内容如下所示:

[http]
    postBuffer = 2M
[user]
    name = runoob
    email = test@runoob.com

也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:

$ git config user.name
runoob

工作流程

一般工作流程如下:

  • 克隆 Git 资源作为工作目录。
  • 在克隆的资源上添加或修改文件。
  • 如果其他人修改了,你可以更新资源。
  • 在提交前查看修改。
  • 提交修改。
  • 在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。

下图展示了 Git 的工作流程:

image-20221025103537525

基本概念(工作区、暂存区和版本库)

  • 工作区:就是你在电脑里能看到的目录。
  • 暂存区:英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • 版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。

下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

img

  • 图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage/index),标记为 "master" 的是 master 分支所代表的目录树。
  • 图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
  • 图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。
  • 当对工作区修改(或新增)的文件执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
  • 当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
  • 当执行 git reset HEAD 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
  • 当执行 **git rm --cached ** 命令时,会直接从暂存区删除文件,工作区则不做出改变。
  • 当执行 git checkout . 或者 **git checkout -- ** 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。
  • 当执行 git checkout HEAD . 或者 **git checkout HEAD ** 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

创建仓库

git init_初始化仓库

Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令。

在执行完成 git init 命令后,Git 仓库会生成一个 .git 目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。

使用方法

使用当前目录作为 Git 仓库,我们只需使它初始化。

git init

该命令执行完后会在当前目录生成一个 .git 目录。

使用我们指定目录作为Git仓库。

git init newrepo

初始化后,会在 newrepo 目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中。

如果当前目录下有几个文件想要纳入版本控制,需要先用 git add 命令告诉 Git 开始对这些文件进行跟踪,然后提交:

$ git add *.c
$ git add README
$ git commit -m '初始化项目版本'

以上命令将目录下以 .c 结尾及 README 文件提交到仓库中。

注: 在 Linux 系统中,commit 信息使用单引号 ',Windows 系统,commit 信息使用双引号 "

所以在 git bash 中 git commit -m '提交说明' 这样是可以的,在 Windows 命令行中就要使用双引号 git commit -m "提交说明"


git clone_下载项目

我们使用 git clone 从现有 Git 仓库中拷贝项目(类似 svn checkout)。

克隆仓库的命令格式为:

git clone <repo>

如果我们需要克隆到指定的目录,可以使用以下命令格式:

git clone <repo> <directory>

参数说明:

  • repo:Git 仓库。
  • directory:本地目录。

比如,要克隆 Ruby 语言的 Git 代码仓库 Grit,可以用下面的命令:

$ git clone git://github.com/schacon/grit.git

执行该命令后,会在当前目录下创建一个名为grit的目录,其中包含一个 .git 的目录,用于保存下载下来的所有版本记录。

如果要自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:

$ git clone git://github.com/schacon/grit.git mygrit

git config_配置

git 的设置使用 git config 命令。

显示当前的 git 配置信息:

$ git config --list
credential.helper=osxkeychain
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true

编辑 git 配置文件:

$ git config -e    # 针对当前仓库 

或者:

$ git config -e --global   # 针对系统上所有仓库

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

$ git config --global user.name "runoob"
$ git config --global user.email test@runoob.com

如果去掉 --global 参数只对当前仓库有效。

基本操作

Git 常用的是以下 6 个命令:git clonegit pushgit addgit commitgit checkoutgit pull,后面我们会详细介绍。

img

image-20230130084643722

说明:

  • workspace:工作区
  • staging area:暂存区/缓存区
  • local repository:版本库或本地仓库
  • remote repository:远程仓库

一个简单的操作步骤:

$ git init    
$ git add .    
$ git commit  
  • git init - 初始化仓库。
  • git add . - 添加文件到暂存区。
  • git commit - 将暂存区内容添加到仓库中。

创建仓库命令

下表列出了 git 创建仓库的命令:

命令 说明
git init 初始化仓库
git clone 拷贝一份远程仓库,也就是下载一个项目。

提交与修改

Git 的工作就是创建和保存你的项目的快照及与之后的快照进行对比。

下表列出了有关创建与提交你的项目的快照的命令:

命令 说明
git add 添加文件到暂存区
git status 查看仓库当前的状态,显示有变更的文件。
git diff 比较文件的不同,即暂存区和工作区的差异。
git commit 提交暂存区到本地仓库。
git reset 回退版本。
git rm 将文件从暂存区和工作区中删除。
git mv 移动或重命名工作区文件。

提交日志

命令 说明
git log 查看历史提交记录
git blame 以列表形式查看指定文件的历史修改记录

远程操作

命令 说明
git remote 远程仓库操作
git fetch 从远程获取代码库
git pull 下载远程代码分支并本地合并
git push 上传远程代码并合并

Git 分支管理

几乎每一种版本控制系统都以某种形式支持分支,一个分支代表一条独立的开发线。

使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。

在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向mastermaster才是指向提交的,所以,HEAD指向的就是当前分支。

一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

git-br-initial

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。

当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

git-br-create

你看,Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!

不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

git-br-dev-fd

假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

git-br-ff-merge

所以Git合并分支也很快!就改改指针,工作区内容也不变!

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

git-br-rm

注意:切换分支这个动作,用switch更科学。因此,最新版本的Git提供了新的git switch命令来切换分支。

分支命令

命令 说明
git branch 列出分支
git branch (branchname) 创建分支
git checkout (branchname)git switch (branchname) 切换分支
git checkout -b (branchname)git switch -c (branchname) 创建+切换分支
git merge (branchname) 合并分支
git branch -d (branchname) 删除分支

查看提交历史

命令 说明
git log 查看历史提交记录
git blame <file> 以列表形式查看指定文件的历史修改记录

标签

命令 说明
git tag 查看所有标签
git tag <tagname> 新建标签,默认为HEAD,也可以指定一个commit id
git tag -a <tagname> -m "blablabla..." 指定标签信息
git blame <file> 以列表形式查看指定文件的历史修改记录
git push origin <tagname> 推送一个本地标签
git push origin --tags 推送全部未推送过的本地标签
git tag -d <tagname> 删除一个本地标签
git push origin :refs/tags/<tagname> 删除一个远程标签

git命令速查

原文件链接:

git-cheat-sheet (gitee.io)

常用 Git 命令清单 - 阮一峰的网络日志 (ruanyifeng.com)

GIT BASICS
git init 在指定的⽬录下创建⼀个空的git repo。不 带参数将在当前⽬录下创建⼀个git repo。 Create empty Git repo in specified directory. Run with no arguments to initialize the current directory as a git repository.
git clone 克隆⼀个指定repo到本地。指定的repo可以是本地⽂件系统或者由HTTP或SSH指定的远程路径。 Clone repo located at onto local machine. Original repo can be located on the local filesystem or on a remote machine via HTTP or SSH.
git config user.name 针对当前repo配置⽤户名。使⽤ --global 参数将配置全局⽤户名。 Define author name to be used for all commits in current repo. Devs commonly use --global flag to set config options for current user.
git add 将指定⽬录的所有修改加⼊到下⼀次 commit中。把替换成<file>将 添加指定⽂件的修改。 Stage all changes in for the next commit. Replace with a <file> to change a specific file.
git commit -m "" 提交暂存区的修改,使⽤指定的 作为提交信息,⽽不是打开⽂ 本编辑器输⼊提交信息。 Commit the staged snapshot, but instead of launching a text editor, use as the commit message.
git status 显示哪些⽂件已被staged、未被staged以 及未跟踪(untracked)。 List which files are staged, unstaged, and untracked.
git log 以缺省格式显示全部commit历史。更多⾃ 定义参数请参考后续部分。 Display the entire commit history using the default format. For customization see additional options.
GIT DIFF
git diff ⽐较⼯作区和暂存区的修改。 Show unstaged changes between your index and working directory.
git diff HEAD ⽐较⼯作区和上⼀次commit后的修改。 Show diference between working directory and last commit.
git diff --cached ⽐较暂存区和上⼀次commit后的修改。 Show diference between staged changes and last commit
UNDOING CHANGES
git revert 对指定创建⼀个undo的 commit ,并应⽤到当前分⽀。 Create new commit that undoes all of the changes made in , then apply it to the current branch.
git reset 将<file>从暂存区移除,但保持⼯作区不 变。此操作不会修改⼯作区的任何⽂件。 Remove <file> from the staging area, but leave the working directory unchanged. This unstages a file without overwriting any changes.
REWRITING GIT HISTORY
git commit -m --amend 将当前staged修改合并到最近⼀次的 commit中。 Replace the last commit with the staged changes and last commit combined.
git rebase 基于对当前分⽀进⾏rebase。 可以是commit、分⽀名称、 tag或 相对于HEAD的commit。 Rebase the current branch onto . can be a commit ID, branch name, a tag, or a relative reference to HEAD.
git reflog 显示本地repo的所有commit⽇志。 Show a log of changes to the local repository’s HEAD.
GIT BRANCHES
git branch 显示本地repo的所有分⽀。 List all of the branches in your repo.
git switch -c 创建并切换到⼀个新的名为的分 ⽀。去掉-c参数将切换到⼀个已有分⽀。 Create and switch to a new branch named . Drop the -c flag to switch to an existing branch.
git merge 将指定分⽀合并到当前分⽀。 Merge into the current branch.
REMOTE REPOSITORIES
git remote -v 查看远程仓库
git remote add 添加⼀个新的远程连接。添加后可使⽤ 作为指定远程连接的名称。 Create a new connection to a remote repo. After adding a remote, you can use as a shortcut for in other commands.
git fetch 从指定抓取指定的所 有commit到本地repo 。去掉将 抓取远程所有分⽀的修改。 Fetches a specific , from the repo. Leave of to fetch all remote refs.
git pull --rebase 从指定抓取所有分⽀的commit 并⽴刻合并到本地repo。 Fetch the specified remote’s copy of current branch and immediately merge it into the local copy.
git push 将本地指定推送到指定远程 。如果远程没有对应的分⽀,将 ⾃动在远程创建此分⽀。 Push the branch to , along with necessary commits and objects. Creates named branch in the remote repo if it doesn’t exist.
git remote rm [别名] 删除远程仓库
GIT CONFIG
git config -- global user.name 配置当前⽤户名,使⽤ --global参数将针对 当前系统登录⽤户⽣效。 Define the author name to be used for all commits by the current user.
git config -- global user.email 配置当前⽤户Email。 Define the author email to be used for all commits by the current user.
git config -- global alias. 配置⼀个git命令的快捷⽅式。例如:配 置”alias.glog log --graph --oneline”使”git glog”相当于”git log --graph --oneline” . Create shortcut for a Git command. E.g. alias.glog “log -- graph --oneline” will set ”git glog”equivalent to ”git log --graph --oneline.
git config -- system core.editor 配置⽂本编辑器,例如vi,在必要时⾃动 打开此⽂本编辑器。 Set text editor used by commands for all users on the machine. arg should be the command that launches the desired editor (e.g., vi).
git config -- global --edit 打开当前⽤户的git全局配置并编辑。 Open the global configuration file in a text editor for manual editing.
GIT LOG
git log - 限制log的显示数量。例如: ”git log -5”仅 显示最新5条commit。 Limit number of commits by . E.g. ”git log -5” will limit to 5 commits.
git log --oneline 每⾏显示⼀条commit。 Condense each commit to a single line.
git log --author= "" 按提交者名字搜索并显示commit。 Search for commits by a particular author.
git log --grep= "" 按指定内容搜索并显示commit。 Search for commits with a commit message that matches .
git log .. 显示指定范围的commit。范围参数可以是 commit ID 、分⽀名称、 HEAD或任意相对 位置。 Show commits that occur between and . Args can be a commit ID, branch name, HEAD, or any other kind of revision reference.
git log -- 仅显示包含指定⽂件修改的commit。 Only display commits that have the specified file.
git log --graph 使⽤ --graph参数显示图形化的branch信 息。 --graph flag draws a text based graph of commits on left side of commit msgs.
GIT RESET
git reset 移除所有暂存区的修改,但不会修改⼯作 区。 Reset staging area to match most recent commit, but leave the working directory unchanged.
git reset --hard 移除所有暂存区的修改,并强制删除所有 ⼯作区的修改。 Reset staging area and working directory to match most recent commit and overwrites all changes in the working directory.
git reset 将当前分⽀回滚到指定,清除 暂存区的修改,但保持⼯作区状态不变。 Move the current branch tip backward to , reset the staging area to match, but leave the working directory alone.
git reset --hard 将当前分⽀回滚到指定,清除 暂存区的修改,并强制删除所有⼯作区的 修改。 Same as previous, but resets both the staging area & working directory to match. Deletes uncommitted changes, and all commits after .
GIT REBASE
git rebase -i 以交互模式对当前分⽀做rebase。 Interactively rebase current branch onto . Launches editor to enter commands for how each commit will be transferred to the new base.
GIT PULL
git pull --rebase 抓取所有远程分⽀,并以rebase模式并⼊ 本地repo⽽不是merge。 Fetch the remote’s copy of current branch and rebases it into the local copy. Uses git rebase instead of merge to integrate the branches.
GIT PUSH
git push --force 将本地分⽀推送到远程。不要使⽤ --force 参数,除⾮你完全明⽩此操作的后果。 Forces the git push even if it results in a non-fast-forward merge. Do not use the --force flag unless you’re absolutely sure you know what you’re doing.
git push --tags 使⽤push命令并不会⾃动将本地tag推送 到远程。加上--tags参数会将所有本地tag 推送到远程。 Tags aren’t automatically pushed when you push a branch or use the --all flag. The --tags flag sends all of your local tags to the remote repo.
posted @ 2023-08-12 09:58  昵称已经被使用  阅读(15)  评论(0编辑  收藏  举报