Git基础教程

Git基础教程

教程的测试环境为win10

安装

Windows下的Git安装一般有两种方式:

  • 通过Cygwin模拟环境,安装Git工具。
  • 安装打包好的Git环境msysgit。其中包括linux下常用的命令和Git,比较方便。

windows下推荐使用msysgit安装,方便快捷。

配置

在正式使用Git进行代码管理之前,需要配置用户名和邮箱信息,告诉git库是谁进行的操作。配置命令如下:


# 配置单项目用户名
git config user.name "gitdemo"

# 配置单项目用户邮箱
git config user.email "gitdemo@51starcard.com"

# 配置全局用户名
git config --global user.name "gitdemo"

# 配置全局用户邮箱
git config --global user.email "gitdemo@51starcard.com"

单项目的配置值将会保存在.git/config文件中,全局配置一般存储在~/.gitconfig文件中。另外还可以通过环境变量GIT_AUTHOR_NAMEGIT_AUTHOR_EMAIL值来实现用户信息配置。

创建初始版本库

Git可以正确使用的条件就是存在使用git管理的代码库,更直白的理解就是必须存在.git目录。创建.git目录即创建初始版本库的命令如下:


# 以gitdemo演示

# 创建代码存储目录
mkdir gitdemo

# 创建初始版本库
git init

关于版本库,Git中区分为开发版本库(一般使用的库)和裸版本库,二者主要的区别在于裸版本库不包含工作目录,而开发版本库则包含工作目录。二者详细的区别和应用可以参考Git 本地仓库和裸仓库博文。

开发

在初始版本库创建完成之后,就可以进行开发了。一般在开发时,都会根据代码的不同功能创建相应的分支,然后再分支上完成相应的开发。在开发和测试完成之后,在合并到master分支。为了后续的代码管理方便,一般不建议直接在master分支上直接进行开发。

  1. 暂存修改
    完成代码编写后,首先需要暂存修改,其中包括保存已追踪文件的修改和未追踪文件添加并保存修改。

    
    # 保存当前目录下的所有修改和未追踪文件
    # 若目标为目录,git会自动递归所有文件
    git add .
    
    
  2. 提交修改 确认所有代码都正常之后就可以使用commit命令提交代码了。

    
    # 每一次提交必须要有相关说明
    git commit -m "一些说明"
    
    

上面的暂存修改和提交修改可以直接通过git commit -am '一些说明'完成。需要注意的是这样会直接提交工作目录中的所有修改,除非确定提交所有,一般不建议使用。

git中的文件状态分为如下三类:

  • 已追踪文件,指已经在版本库中的文件,或者已暂存到索引中的文件。
  • 忽略文件,由.gitignore声明的项目中不需要进行管理的文件。
  • 未追踪文件,指除去已追踪和忽略文件之后,剩余的文件。

分支的相关操作将会在后面专门介绍。

以上就是一般的git使用过程。


Git文件操作

  1. 添加文件
    Git通过add命令将新添加的未追踪的文件添加到代码库中。常见参数说明:

# git add -h

usage: git add [<options>] [--] <pathspec>...

    -n, --dry-run         以演习得方式操作
    -v, --verbose         列出详细信息

    -i, --interactive     交互模式添加文件
    -p, --patch           交互的方式批量添加
    -e, --edit            编辑当前修改并应用
    -f, --force           强制添加被忽略的文件
    -u, --update          仅添加已追踪的文件
    -N, --intent-to-add   仅记录会添加的目录
    -A, --all             添加所有追踪的和未追踪文件的修改
    --ignore-removal      忽略工作目录中已删除的目录
    --refresh             仅刷新索引不执行添加操作
    --ignore-errors       忽略文件中错误
    --ignore-missing      检查在演习模式下文件是否被忽略了
    --chmod <(+/-)x>      文件权限修改

  1. 删除文件
    Git通过rm命令删除版本库中已追踪的文件,该命令会同时删除工作目录和版本库中的文件。另外需要注意的是,从工作目录和索引中删除一个文件,并不会删除该文件在版本库中的历史记录。要将一个文件由已追踪状态转换为未追踪状态,可以使用git rm --cached命令。

# git rm -h

usage: git rm [<options>] [--] <file>...

    -n, --dry-run         以演习得方式操作
    -q, --quiet           不显示被删除的文件
    --cached              仅从索引中删除该文件
    -f, --force           忽略文件最新版本检查,强制删除
    -r                    允许递归删除
    --ignore-unmatch      即使未匹配任何文件,也不报错

  1. 文件移动(重命名)
    对于文件的重命名或者移动,可以通过组合git rmgit add命令实现,也可以通过git mv命令来实现。两种方式的操作结果最终是一样的,更新索引并重新关联到原对象。

# git mv -h

usage: git mv [<options>] <source>... <destination>

    -v, --verbose         显示详细的信息
    -n, --dry-run         以演习得方式操作
    -f, --force           即使目标文件已存在,依旧执行操作。
    -k                    忽略操作中的错误

  1. .gitignore文件说明
    Git可以通过.gitignore忽略任何文件。一般可以通过将想要忽略的文件名添加到该目录下的.gitignore文件中或者将该文件添加到顶层目录中的.gitignore中。.gitignore规则如下:
    • 空行会被忽略,以#好开头的行可以用于注释。
    • 一个简单的字面值文件名匹配任何目录中的同名文件。
    • 目录名由末尾的反斜杠标记,能匹配同名的目录和子目录,但是不能匹配文件或符号链接。
    • 包含shell通配符,此种模式可以扩展未shell通配模式。
    • 启示的感叹号会对该行其余部分的模式进行取反。取反模式会覆盖低优先级的规则。

常见的.gitignore规则可以参考github/gitignore


Git分支管理

Git相比于其它的版本控制工具,其中一大优势就在与分支操作和管理的方便快捷。恰当的使用Git的分支管理功能会大幅提高团队开发的效率,同时减少多人同时修改同一文件发生错误的次数。

  1. 创建分支
    git branch命令可创建分支,相关语法和参数如下:

    
    # git branch -h
    
    usage: git branch [<options>] [-r | -a] [--merged | --no-merged]
    or: git branch [<options>] [-l] [-f] <branch-name> [<start-point>]
    or: git branch [<options>] [-r] (-d | -D) <branch-name>...
    or: git branch [<options>] (-m | -M) [<old-branch>] <new-branch>
    or: git branch [<options>] [-r | -a] [--points-at]
    
    Generic options
    -v, --verbose         显示详细信息
    -q, --quiet           不提示消息
    -t, --track           设置未追踪模式
    --set-upstream        设置上游信息
    -u, --set-upstream-to <upstream>    设置上游
    --unset-upstream      取消上游设置
    --color[=<when>]      输出着色
    -r, --remotes         在远程仓库分支执行
    --contains <commit>   仅显示包含指定提交的分支
    --abbrev[=<n>]        以n位字节显示sha1值
    
    Specific git-branch actions:
    -a, --all             显示远程和本地分支
    -d, --delete          删除已合并分支
    -D                    删除并未合并的分支
    -m, --move            移动或重命名分支
    -M                    强制移动或重命名分支
    --list                列出分支名称
    -l, --create-reflog   创建分支的引用历史
    --edit-description    编辑分支的说明
    -f, --force           强制执行创建,移动,删除等操作
    --merged <commit>     列出已合并分支
    --no-merged <commit>  列出未合并分支
    --column[=<style>]    list branches in columns
    --sort <key>          设置排序字符串键
    --points-at <object>  列出含有某个文件的分支
    
    

    一般而言创建分支命令为:

    
    # 从当前提交创建分支dev
    git branch dev
    
    # 从ft/gitdemo提交创建分支dev
    git branch dev ft/gitdemo
    
    
  2. 删除分支

    
    # 删除已合并dev分支
    git branch -d dev
    
    # 删除未合并dev分支
    git branch -D dev
    
    
  3. 检出分支
    Git的工作目录一次只能反映一个分支,要在不同的分支上进行工作,就需要使用git checkout命令进行检出。git checkout改变了工作树文件和目录结构。

    
    # 创建bug/pr-01分支
    git branch bug/pr-01
    
    # 检出到bug/pr-01分支
    git checkout bug/pr-01
    
    
    
    usage: git checkout [<options>] <branch>
    or: git checkout [<options>] [<branch>] -- <file>...
    
    -q, --quiet           不显示进度信息
    -b <branch>           创建并检出该分支
    -B <branch>           创建或重置,并检出该分支
    -l                    为新分支创建引用历史
    --detach              detach HEAD at named commit
    -t, --track           设置分支的上游信息
    --orphan <new-branch> 新分支无父对象
    -2, --ours            checkout our version for unmerged files
    -3, --theirs          checkout their version for unmerged files
    -f, --force           强制检出分支
    -m, --merge           对待检出分支执行合并操作
    --overwrite-ignore    更新忽略的文件
    --conflict <style>    conflict style (merge or diff3)
    -p, --patch           交互式批量操作
    --ignore-skip-worktree-bits do not limit pathspecs to sparse entries only
    --ignore-other-worktrees do not check if another worktree is holding the given ref
    --progress            强制显示进度信息
    
    
    

在有未提交的内容时,执行检出操作,若是工作目录中的未被追踪的文件,则会置之不理,若是一个文件的修改不同与待检出分支上的内容,则Git会报错并结束检出操作。对于存在冲突的情况可以使用-m参数来执行合并操作,在检出完成之后再解决冲突。

  1. 分支合并
    git中合并分支有git mergegit rebase两个命令。

    1. merge操作
      merge的流程一般是,寻找两个分支的共同祖先,然后进行三方比较,生成合并后的内容。
    2. rebase操作
      rebase操作流程一般是寻找到两个分支的祖先,比较得出待合并分支的变化内容,接着在base分支上将变化内容执行一遍,生产合并后的内容。

    merge和rebase合并操作得到的结果理论上来说是一样的,但是二者生成的log记录是不同的,rebase命令的更加清晰,为单条主线演进,而merge则为多条分支演进,理解桑也较为繁琐。

    
    usage: git merge [<options>] [<commit>...]
    or: git merge [<options>] <msg> HEAD <commit>
    or: git merge --abort
    
    -n                    不显示受影响的地方
    --stat                显示受影响的地方
    --summary             等同于 --stat
    --log[=<n>]           添加简短的日志的commit的说明中
    --squash              已commit的方式替换merge
    --commit              合并成功之后,执行commit操作
    -e, --edit            commit之前编辑说明
    --ff                  快进合并
    --ff-only             只执行快进合并,否则退出
    --rerere-autoupdate   尝试用之前的冲突解决方案来解决冲突
    --verify-signatures   执行GPG签名验证
    -s, --strategy <strategy> 设置合并的策略
    -X, --strategy-option <option=value> 合并策略的相关选项
    -m, --message <message> merge之后执行commit的说明
    -v, --verbose         显示更多信息
    -q, --quiet           静默执行
    --abort               结束正在执行的合并
    --allow-unrelated-histories 允许合并无关的分支
    --progress            不显示合并进程信息
    -S, --gpg-sign[=<key-id>] GPG签名
    --overwrite-ignore    更新忽略的文件
    
    
    
    usage: git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
    or: git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
    or: git-rebase --continue | --abort | --skip | --edit-todo
    
    Available options are
    -v, --verbose         显示详细信息
    -q, --quiet           静默执行
    --autostash           自动加入stash中的内容
    --fork-point          use 'merge-base --fork-point' to refine upstream
    --onto ...            变基到指定分支
    -p, --preserve-merges try to recreate merges instead of ignoring them
    -s, --strategy ...    使用指定的合并策略
    --no-ff               cherry-pick all commits, even if unchanged
    -m, --merge           使用合并的方式来进行变基操作
    -i, --interactive     交互式执行
    -x, --exec ...        设置每一次commit之后的执行命令
    -k, --keep-empty         保存空的commit
    -f, --force-rebase    强制执行
    -X, --strategy-option ... 合并策略的选项
    --stat                显示受影响的内容
    -n, --no-stat         不显示受影响的内容
    --verify              允许pre-rebase钩子执行
    --rerere-autoupdate   尝试用之前的冲突解决方案来解决冲突
    --root                rebase all reachable commits up to the root(s)
    --autosquash         move commits that begin with squash
                          move commits that begin with squash!/fixup! under -i
    --committer-date-is-author-date
                          passed to 'git am'
    --ignore-date         passed to 'git am'
    --whitespace ...      passed to 'git apply'
    --ignore-whitespace   passed to 'git apply'
    -C ...                passed to 'git apply'
    -S, --gpg-sign[=...]  GPG签名
    
    Actions:
    --continue            continue
    --abort               abort and check out the original branch
    --skip                skip current patch and continue
    --edit-todo           edit the todo list during an interactive rebase
    
    

rebase尽量在本地分支上执行,不要在公有分支上进行操作,若要执行rebase最好告知其它人员。


储藏区(stash)使用

储藏区一般在多分枝开发的情况下使用较多。例如,日常开发中,我们在featureA上进行开发,但是在开发中,临时需要解决bug。这时候如果我们在featureA上去解决bug,那么featureA的代码就乱了。若是想新建分支,则又需要将未完成的开发提前提交,这最终会导致自己的管理混乱。这时比较高效的解决办法就是使用储存区将featureA上的修改暂时存储,然后新建bug分支,在完成了bug的修复之后,再恢复储存区中保存的featureA中的修改内容。

  1. 保存

git stash

git stash save

  1. 恢复

git pop

git apply

  1. 删除

git stash drop

git stash clear

  1. 查看

git stash list

git stash show

git中的存储区是以堆栈的形式来操作的,在日常开发中需要灵活使用。记得清理暂存区。


标签

Git中使用SHA-1值来标记每一次commit,可是这种方式缺少可读性。在版本演变的关键节点,可能需要记录相关信息,若是使用SHA-1值,则记录麻烦且缺乏可读性。这是就可以通过给commit打上tag的方式来解决这种问题。实际上Git中的tag仅仅是对commit的“指针”,但是可读性更高。
Git中的tag分为两类,一般式和标注式。其中标注式需要挟带操作人的签名信息,而一般式则不包含。


# 在当前commit上,新建tag,v1.1
git tag v1.1

# 在45dfg8,commit上,新建tag,v1.1
git tag v1.2 45dfg8

# 在当前commit上,新建标注式tag, v1.3
git tag -a v1.3 -m '这是1.3版本'

建议在代码版本演进的关键节点,打上相应标注式tag,以便于管理。


Git远程仓库和本地仓库互操作

  1. 克隆远程仓库代码

# 克隆demourl出的代码到demo目录
git clone demourl demo

  1. 推送本地commit到远程仓库

# 推送到远程仓库的master分支
git push origin master

origin是远程仓库的“简称”,可以设定为任意合法名称,并非只能为origin。

  1. 本地现有仓库关联远程仓库

# 本地master分支关联demourl的master分支
git remote add origin demourl

  1. 本地分支关联远程仓库分支

# 本地dev分支关联远程仓库的dev分支
git branch --set-upstream-to origin/dev

# 取消本地分支和远程分支关联
git branch --unset-upstream

  1. 推送本地标签到远程仓库

git push --tags origin master

  1. 拉取远程commit

git pull origin master

git fetch origin master

pull和fetch的主要区别在于,pull是fetch和merge的合并。


usage: git push [<options>] [<repository> [<refspec>...]]

    -v, --verbose         显示详细信息
    -q, --quiet           静默执行
    --repo <repository>   远程代码仓库
    --all                 推送所有引用
    --mirror              mirror all refs
    -d, --delete          删除远程分支
    --tags                推送标签
    -n, --dry-run         预演执行
    --porcelain           机器可读的输出
    -f, --force           强制更新
    --force-with-lease[=<refname>:<expect>]
                          require old value of ref to be at this value
    --recurse-submodules[=<check|on-demand|no>]
                          control recursive pushing of submodules
    --thin                use thin pack
    --receive-pack <receive-pack>
                          receive pack program
    --exec <receive-pack>
                          receive pack program
    -u, --set-upstream    set upstream for git pull/status
    --progress            强制显示进度
    --prune               prune locally removed refs
    --no-verify           bypass pre-push hook
    --follow-tags         推送丢失但是相关的标签
    --signed[=<yes|no|if-asked>]
                          GPG sign the push
    --atomic              远程仓库执行原子操作
    -o, --push-option <server-specific>
                          option to transmit
    -4, --ipv4            use IPv4 addresses only
    -6, --ipv6            use IPv6 addresses only


usage: git remote [-v | --verbose]
   or: git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--mirror=<fetch|push>] <name> <url>
   or: git remote rename <old> <new> => 重命名远程仓库
   or: git remote remove <name> => 删除远程仓库
   or: git remote set-head <name> (-a | --auto | -d | --delete | <branch>) => 设置远程仓库head引用
   or: git remote [-v | --verbose] show [-n] <name> => 显示远程仓库详细信息
   or: git remote prune [-n | --dry-run] <name>
   or: git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]
   or: git remote set-branches [--add] <name> <branch>...
   or: git remote get-url [--push] [--all] <name> => 获取url地址
   or: git remote set-url [--push] <name> <newurl> [<oldurl>] => 设置url地址
   or: git remote set-url --add <name> <newurl> => 设置url地址, 添加新的url
   or: git remote set-url --delete <name> <url> => 设置url地址,删除url

    -v, --verbose         显示详细信息


最后更新日期:2017-09-07

转载于:https://my.oschina.net/taodf/blog/2218931

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值