如何使用Git和GitHub

结合了Udacity上《如何使用Git和GitHub》的课程笔记和廖雪峰老师关于git的博客内容。

git

git简介

集中式vs分布式

  • SVN是集中式的版本控制系统,版本库是集中存放在中央服务器的。

  • Git是分布式版本控制系统,每个人的电脑上都是一个完整的版本库。

安装git

由于之前已经安装过了,首先我想查看这台电脑上的git bash中用户名和邮箱的配置

1
2
3
// 查看命令
git config user.name
git config user.email

之前配置了一个全局的用户名和邮箱,想在项目根目录下进行单独的配置

1
2
3
// 全局配置
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
1
2
3
4
5
// practice/github文件夹下单独配置
$ git config user.name "Your Name"
$ git config user.email "email@example.com"
// 查看
git config --list // 会显示全局和当前的用户名和邮箱
  • 注意:一开始运行了git config报错,not in a git directory,运行一下代码
1
2
git init gitTest
cd gitTest

也可以新建文件夹进入之后,git init即可,会产生一个.git目录,如果没有产生的化可能是默认隐藏了,可以使用ls -ah来查看,这个目录不需要手动修改。

创建版本库

  • 只用UTF-8(UTF-8 without BOM)编码

  • 编写readme.txt

  • 使用git add把文件添加到仓库

    git add readme.txt

  • 使用git commit把文件提交到仓库

    git commit -m "this is a readme file"

    -m 后面的是本次提交的说明
    可以多次add,一起commit

1
2
3
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

时光穿梭机

git status – 当前仓库状态
git diff – 查看做了什么修改

版本回退

git log – 从最近到最远的提交日志

git log –pretty=oneline – 简化日志输出

git reset –hard commit_id – 回退到某一个历史版本(id不用输全,大于四位即可)

又想回到当前id之后的版本

git reflog – 查看命令历史

然后再使用git reset

工作区和暂存区

工作区:当前文件夹
版本库:工作区中的隐藏目录.git
repository
git add 把文件修改添加到暂存区
git commit 把暂存区的所有内容提交到当前分支

管理修改

git跟踪并管理的是修改,而非文件
一定要先git add到暂存区,才能加入commit

撤销修改

git checkout – file – 可以丢弃工作区的修改(还未add)
已经add的情况下,还未commit
git reset HEAD file – 吧暂存区的内容回退到工作区
再丢弃工作区的修改。

删除文件

rm file – 删除文件
删除之后会版本库有,工作区没有
如果确认的话就使用git commit 提交
如果误删的话就是用git checkout – file 用版本库的替代工作去的
所以只要commit提交过就不用慌误删

远程仓库

  • 创建ssh key,有了的话可以跳过
1
ssh-keygen -t rsa -C "youremail@example.com"

可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

  • 登陆github-setting-ssh keys-add ssh key-复制id_rsa.pub文件中的内容

添加远程库

把本地库的内容推送到远程
远程库的名字就是origin(默认,可以改),-u是第一次推送的时候要加,会把本地master分支和远程的master分支关联起来。
之后提交的话只要 git push origin master

从远程库克隆

Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。

分支管理

创建与合并分支

git checkout -b dev – 创建dev分支,切换到dev分支
-b 表示创建并切换,相当于:
git branch dev
git checkout dev

git branch – 查看当前分支
git checkout master – 切换回master分支
git merge dev – 把dev分支的工作成果合并到master分支上
git branch -d dev – 删除dev分支

解决冲突

发生冲突之后(两个分支上都commit之后,merge的时候),使用git status可以查看发生冲突的文件,打开文件可以看到git为我们标记出了不同分支的内容。
修改完成后,git add & git commit。

git log --graph --pretty=oneline --abbrev-commit – 可以查看分支的合并情况

然后删除被合并的分支,就完成了。

分支管理策略

git merge --no-ff -m "merge with no-ff" dev – 禁用fast forward,在merge时生成一个新的commit
–no-ff参数

Bug分支

场景:当你接到一个修复一个代号为101的bug的任务时,你想创建一个分支issue-101来修复,但是你当前正在的dev上进行的工作还没有提交,工作进行到一半,没法提交。

把你的文件git add之后,使用
git stash – 把当前工作现场储藏起来
在输入git status,发现当前工作区是干净的。

把bug修复完成合并到master分支之后,在回到dev分支继续之前的工作。
git stash list – 查看储藏的列表

有两种方式恢复
git stash apply stash@{0} – 恢复,但stash内容不删除
git stash drop – 删除stash内容

git stash pop – 恢复且删除

feature分支

开发一个新feature,最好新建一个分支;

如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。(注意要先切换到别的分支再删除)

多人协作

git remote – 查看远程库的信息
git remote -v – 显示更详细的信息

git push origin master – 推送本地master分支到远程origin

但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?

  • master分支是主分支,因此要时刻与远程同步;
  • dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
  • bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
  • feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

总之,就是在Git中,分支完全可以在本地自己藏着玩,是否推送,视你的心情而定!

推送分支

推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

1
$ git push origin master

如果要推送其他分支,比如dev,就改成:

1
$ git push origin dev

抓取分支

git checkout -b dev origin/dev – 在git clone远程的master分支后,git branch只有master分支,要使用这命令创建远程的dev分支,然后继续修改

当有小伙伴已经向origin/dev分支提交了推送,并且你也恰巧对该文件做了修改,并试图推送
git push origin dev
失败
git pull
失败,因为你没有指定本地dev和远程origin/dev分支的连接,根据提示:
git branch –set-upstream-to=origin/dev dev
修改conflict,在提交 推送。

因此,多人协作的工作模式通常是这样:

  • 首先,可以试图用git push origin <branch-name>推送自己的修改;
  • 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
  • 如果合并有冲突,则解决冲突,并在本地提交;
  • 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!
  • 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>

这就是多人协作的工作模式,一旦熟悉了,就非常简单。

Rebase

git rebase – rebase操作可以把本地未push的分叉提交历史整理成直线;

标签管理

标签也是版本库的一个快照。
tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。

创建标签

  • 切换到需要打标签的分支上
  • git tag <name> – 打一个新标签
  • git tag – 查看所有标签
  • git tag <name> <commit id> – 给之前的commit打标签
  • git show <name> – 查看标签信息
1
git tag -a v0.1 -m "version 0.1 released" 1094adb

-a指定标签名,-m指定说明文字。

注意:标签总和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么两个分支上都可以看到这个标签。

操作标签

git tag -d v0.1 – 删除标签
git push origin v0.1 – 推送标签到远程
git push origin –tags – 推送所有尚未推送的本地标签

删除已经推送的标签需要,
先删除本地标签: git tag -d v0.9
再从远程删除: git push origin :refs/tags/v0.9

使用GitHub

如何参与一个开源项目

  • fork
  • 从自己的账号下clone项目
  • 然后你可以推送修改,但是仅限自己的仓库
  • 如果你想和官方协作的话,你可以在GitHub上发起一个pull request,需要对方接受。

使用码云

自定义Git

git config –global color.ui true

忽略特殊文件

忽略某些文件时,需要编写.gitignore;
.gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理!

配置别名

给Git配置好别名,就可以输入命令时偷个懒。我们鼓励偷懒。

搭建Git服务器

期末总结

一份git cheat sheet
官网:https://git-scm.com/doc

感觉廖老师这份指南已经很清楚了,主要是实际运用,忘记了再查看就好了。

git tree