git学习笔记

git学习笔记

系统的学习了一下廖雪峰老师的git教程。

参考

  1. 廖雪峰git教程

简介

git是世界上最先进的分布式版本控制系统。

git是linux之父linus大神花了两个星期用c写的。。。

安装

1
git --version	#查看机器上是否有git以及版本号

windows:

直接下载gitbash:https://git-scm.com/downloads

linux/macos

1
2
3
4
sudo apt-get install git	#debian/ubuntu安装
sudo apt-get install git-core #老版本debian/ubuntu安装
yum install git #centos/RHEL安装
brew install git #macos安装,需要先安装homebrew包管理工具

使用

配置名称和邮件

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

创建版本库

1
2
3
4
#linux和macos没问题,提醒一下windows不要使用cmd/powershell,使用gitbash
mkdir gitDir
cd gitDir
git init #在gitDir目录下初始化git仓库

仓库中.git目录用来跟踪管理版本库,不要修改!

1
ls -lha	#查看.git目录,-lha三个参数分别为列表显示、人性化显示、全部显示(显示以.开头的文件)

在非空目录下 git init 也可

把文件添加到版本库

git仅可以跟踪文本文件的变动,对于二进制文件仅可以知道其改动了

ps:二进制文件非常多,包括office三兄弟

文本文件使用utf-8编码

切勿使用新建记事本文件,记事本为utf-8 with BOM编码,若使用notepad++则改为utf-8 without BOM编码

命令
  1. git仓库中新建一个readme.txt文件:
1
2
Git is a version control system.
Git is free software.
  1. git add 命令把文件添加到仓库
1
2
3
4
5
git add readme.txt
#执行完无显示则表示成功
git add .
git add *
git add -u # 自动追踪更新的文件
  1. git commit 把文件提交到仓库
1
git commit -m 'wrote a readme.txt file'	# -m后面为本次commit的说明

为什么Git添加文件需要 addcommit 一共两步呢?因为 commit 可以一次提交很多文件,所以你可以多次 add 不同的文件,比如:

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

即add一次可以add一个或者多个文件,而commit则一次性把add的文件提交

  1. 重命名文件名
1
git mv file_old_name file_new_name
小结

初始化一个Git仓库,使用 git init 命令。

添加文件到Git仓库,分两步:

  1. 使用命令 git add ,注意,可反复多次使用,添加多个文件;
  2. 使用命令 git commit -m ,完成。

回滚

修改readme.txt文件为:

1
2
Git is a distributed version control system.
Git is free software.

运行 git status 可以看到仓库状态和哪些文件被修改了。

1
git status

运行 git diff 查看修改了什么内容

1
git diff readme.txt

再提交

1
2
git add readme.txt
git commit -m 'readme.txt has been modified'

看状态

1
2
git status
# 提示没有需要提交的修改,工作目录干净
版本回退

git log 查看历史记录

1
git log	# 从上到下是从近期到以前的commit

如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline 参数:

1
git log --pretty=online

或者

1
git log --oneline

最近4次的记录

1
git log -n4 --oneline

图形化显示

1
git log --oneline --graph

commit id是SHA1计算出来的16进制大数(为防止冲突)

版本回退:

当前版本为 HEAD ,上一个版本为 HEAD^ , 上100个版本为 HEAD~100
回退上一个版本:

1
git reset --hard HEAD^

退回特定版本:

1
git reset --hard commit-id	#版本号可以只写前几位

版本回退仅仅是吧HEAD指针指向当前版本

git reflog 用来记录每一条git命令,可以用来找以前的commit id

1
git reflog

小结:

  1. HEAD 指向当前版本
  2. 版本回退命令: git reset --hard commit-id
  3. git log 查看提交历史,以便决定回退到哪个版本
  4. git reflog 查看历史命令,以便决定回退到哪个版本

工作区和暂存区

1
2
3
mkdir gitDir
cd gitDir #gitDir就是工作区
ls -lha #可以看到.git目录,.git就是版本库

版本库中有一个叫stage的暂存区、master分支和HEAD指针

git add 就是把文件添加进暂存区

git add 是把暂存区文件提交到当前分支

若之后未对工作区做任何修改,则工作区clean

1
2
3
git status
#On branch master
#nothing to commit, working tree clean

此时版本库变为:

总结:

Git管理的文件分为:工作区,版本库,版本库又分为暂存区stage和暂存区分支master(仓库)

工作区>>>>暂存区>>>>仓库

git add 把文件从工作区>>>>暂存区,git commit把文件从暂存区>>>>仓库,

git diff 查看工作区和暂存区差异,

git diff --cached 查看暂存区和仓库差异,

git diff HEAD 查看工作区和仓库的差异,

git add 的反向命令git checkout,撤销工作区修改,即把暂存区最新版本转移到工作区,

git commit 的反向命令git reset HEAD,就是把仓库最新版本转移到暂存区。

修改管理

git跟踪的是修改而不是文件。

第一次修改完一个文件后 git add ,再第二次修改这个文件,然后再 git commit ,只会提交第一次修改,故而git跟踪的是修改而不是文件。现在要提交第二次修改只需要: git add 这个文件,再 git commit 就行了,或者第一次修改完了不要急着 git add ,等着两次修改完了一起 git add git commit

撤销修改

git checkout -- filename :将文件咋工作区的修改完全撤销

作用是让这个文件回到最近一次 git commit 或者 git add 时候的状态:

一种是 readme.txt 自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是 readme.txt 已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

git reset HEAD filename 可以把暂存区修改撤销

git reset 既可以回退版本也可以吧暂存区修改回退到工作区

小结

情况一:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令 git checkout -- file

情况二:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令 git reset HEAD ,就回到了场景1,第二步按场景1操作。

情况三:已经提交了不合适的修改到版本库时,想要撤销本次提交,使用版本回退。

情况四:如果已经push到了远程仓库,完蛋。

简而言之:

  1. 没有 git add 时,用 git checkout -- file 回退到与版本库最新版一致

  2. 已经 git add 时,先 git reset HEAD 回退到1.,再按1. 操作

  3. 已经 git commit 时,用 git reset 回退版本

  4. 推送到远程库,GG

删除文件

  1. 先直接删除文件
  2. 使用 git rm 从版本库中删除该文件
  3. git commit 提交更改

若误删文件,则用 git checkout -- filename 从版本库中恢复到工作区

远程仓库

我一般使用github

本地git仓库和github仓库的传输通过ssh加密,故而本地要创建ssh key:

1
ssh-keygen -t -C "youremail@example.com"

一路回车既可,无需设置密码

~/.ssh/ 下面有有 id_rsaid_rsa.pub 两个文件

登录github-setting-add ssh key,填写title,粘贴pub里的内容到上面,点击add key。

GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。

github仓库为公开,不要提交敏感信息

可以搭建git服务器保护代码

搭建git服务器

以ubuntu/debian为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo apt-get install git	# 服务器安装git
sudo adduser git # 创建一个用户git,用来运行git服务
sudo git init --bare sample.git # 创建证书登录,收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。
sudo git init --bare sample.git # 初始化git仓库,选择一个目录用作git仓库,--bare创建了一个裸仓库,没有工作区
sudo chown -R git:git sample.git # 将owner改为git

# 禁用ssh登录:
# 出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:
git:x:1001:1001:,,,:/home/git:/bin/bash
# 改为
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
# 这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

git clone git@server:/srv/sample.git # 克隆远程仓库

管理公钥:

小团队管理:把团队中每个人的公钥收集起来放到服务器的 /home/git/.ssh/authorized_keys 文件里就可以。

大团队管理:使用gittosis。

git不支持权限管理!!!

添加远程仓库
  1. 先在github上创建一个新的仓库
  2. 本地仓库 git remote add origin git@github.com:herotiga/Python-100-Days.git
  3. 第一次推送本地文件到远程仓库: git push -u origin master
  4. 以后只需要 git push origin master
ssh警告

第一次使用git clone or git push连接github会有警告

小结
  1. 关联远程仓库: git remote add origin git@github.com:herotiga/learngit.git
  2. 关联后,使用 git push -u origin master 第一次推送master分支
  3. 之后每次只需要 git push origin master
从远程仓库克隆
1
git clone git@github.com:herotiga/asd.git

注意:克隆下来的是一个目录

一般使用ssh,添加了ssh key之后无需输入密码。而https需要输入密码。

小结

git clone 将项目克隆下来,一般使用ssh(除非公司内部只能使用https)。

分支管理

创建分支
1
git checkout -b dev	# 创建分支dev并切换到dev分支,-b表示创建完了切换上去

以上命令等同于:

1
2
git branch dev
git checkout dev

查看当前分支

1
git branch

当前分支前面会有*

或者

1
git status
合并分支
1
git merge dev	# 将dev分支合并到当前分支上
删除分支
1
git branch -d dev
切换分支
1
2
3
git switch -c dev	# 创建并切换到新的dev分支

git switch master # 切换到已经有的分支,比如master分支
小结
1
2
3
4
5
git branch	# 查看分支
git branch branchName # 创建分支
git checkout branchName / git switch branchName #切换分支
git merge branchName # 合并分支到当前分支
git branch -d branchName # 删除分支

不完整,仍需补充

评论