感谢廖老师出品Git教程,浅显易懂。
0. 总结
- 初始化一个Git仓库:
git init
- 添加文件到Git仓库step1:
git add <file>
- 添加文件到Git仓库step2:
git commit -m <message>
- 要随时掌握工作区的状态,使用:
git status
- 如果git status告诉你有文件被修改过,用:
git diff
查看修改内容 HEAD
指向的版本就是当前版本,因此可以在各个版本之间穿梭,git reset --hard eb69 (回到eb69版本)
,或git reset --hard HEAD^ (回退到前一个版本)
- 穿梭前,用
git log
可以查看提交历史,以便确定要回退到哪个版本,或是简介版git log --pretty=oneline
- 要重返未来,用
git reflog
查看命令历史,以便确定要回到未来的哪个版本 - 查看当前仓库版本,与工作区版本的差别:
git diff HEAD -- readme.txt
- 丢弃工作区的修改时,用命令:
git checkout -- readme.txt
- 丢弃暂存区的修改,用命令:
git reset HEAD readme.txt
- 删除暂存区的文件,
git rm
,与git add
一样地位的命令,然后git commit
提交到仓库 - 本地创建SSH Key,
ssh-keygen -t rsa -C "lijun.kawasaki@gmail.com"
- 要关联一个远程库,使用命令:
git remote add origin https://github.com/utanesuke0612/learngit.git
- 关联后,使用命令:
git push -u origin master
第一次推送master分支的所有内容 - 每次本地提交后,使用:
git push origin master
推送最新修改 - 用命令
git clone https://github.com/utanesuke0612/udacitystudy.git
克隆一个远程库到本地 - 查看分支:
git branch
- 创建分支:
git branch <name>
- 切换分支:
git checkout <name>
- 创建+切换分支:
git checkout -b <name>
- 合并某分支到当前分支:
git merge <name>
` - 删除分支:
git branch -d <name>
- 如果两个不同分支上,针对同一个文件进行了修改,在合并分支的时候,可能会出现合并冲突,这时候要手动解决冲突,然后再添加并提交。
- 通过
git log --graph
命令可以看到分支合并图。 - 通过这种方式merge,能够保留分支上的信息,
git merge --no-ff -m "merge with no-ff" dev
- 通过
git log --graph --pretty=oneline --abbrev-commit
查看分支历史 - 当手头工作没有完成时,先把工作现场
git stash
一下,然后去修复bug,修复后,再git stash pop
,回到工作现场。 - 开发一个新feature,最好新建一个分支
- 如果要丢弃一个没有被合并过的分支,可以通过git branch -D
强行删除 - 查看远程信息用
git remote
,更详细信息用git remote -v
- 创建远程origin的dev分支到本地:
git checkout -b dev origin/dev
- 用
git push origin dev
推送自己的修改 - 如果推送失败,是因为远程分支比本地版本更新,需要使用
git pull
更新到本地 - 如果更新到本地时有冲突,则解决冲突后再add-commit-push
- 如果
git pull
提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream dev origin/dev
- 敲命令
git tag <name>
就可以打一个新标签,默认标签是打在最新提交的commit上 - 通过后面的commitid
git tag v0.9 5508
,可以将变迁打在历史版本上 - 通过
-m
可以给标签添加信息:git tag -a v0.8 -m "ver0.8 released" ca3e
- 命令
git tag
可以查看所有标签。 - 显示指定标签
git show v0.8
- 命令
git push origin v1.0
可以推送一个本地标签 - 命令
git push origin --tags
可以推送全部未推送过的本地标签 - 命令
git tag -d v0.9
可以删除一个本地标签 - 命令
git push origin :refs/tags/v0.9
可以删除一个远程标签 - 忽略某些文件时,需要编写
.gitignore
- 强制添加文件到仓库
git add -f Desktop.ini
- 查看是哪条ignore命令限定了指定文件:
git check-ignore -v Desktop.ini
- 可以通过
git config --global alias.st status
配置命令的别名,添加–global表示针对用户有效,不加是针对仓库有效 - 通过Ubuntu可以很简单的搭建自己的git服务器,具体步骤参考[6.3 搭建Git服务器]
0. 小结(cheetsheet)
1. Git简介
1. 安装Git
Linux:
使用$ git
或sudo apt-get install git
(Ubuntu),
另外,MAC上通过XCode直接安装。
Windows:
直接官网下载安装,菜单中有 Git->Git Bash说明安装成功。
安装完成后,还需要最后一步设置,在命令行输入:
$ git config --global user.name "utane"
$ git config --global user.email "lijun.kawasaki@gmail.com"
注意git config
命令的--global
参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置。
2. 创建版本库
这个目录里面所有文件都可以被Git管理,修改删除等都能跟踪,以便任何时候都能追踪历史和还原。
- 选择合适位置创建空目录:
utane@ubuntu:~$ mkdir learngit
utane@ubuntu:~$ cd learngit/
utane@ubuntu:~/learngit$ pwd
/home/utane/learngit
- 通过
git init
命令把这个目录变成Git可以管理的仓库:
utane@ubuntu:~/learngit$ git init
Initialized empty Git repository in /home/utane/learngit/.git/
通过下面的命令,可以看到创建了对应的目录,.git
这个目录是Git来跟踪管理版本库的。
utane@ubuntu:~/learngit$ ls -ah
. .. .git
- 对应目录下添加文件
utane@ubuntu:~/learngit$ vim readme.txt
新建一个文件readme.txt
并写入如下内容:
Git is a version control system.
Git is free software.
- step1:将文件添加到仓库
git add
:
utane@ubuntu:~/learngit$ git add readme.txt
- step2:把文件提交到仓库
git commit
:
utane@ubuntu:~/learngit$ git commit -m "wrote a readme file"
[master (root-commit) 4568339] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
utane@ubuntu:~/learngit$
2. 时光穿梭
现在我们来修改刚才的文件,添加一行:
Git is a version control system.
Git is free software.
add more @1st
运行git status
可以查看仓库的当前状态:
utane@ubuntu:~/learngit$ git status
ブランチ master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
用git diff
这个命令看看修改的内容:
utane@ubuntu:~/learngit$ git diff
diff --git a/readme.txt b/readme.txt
index 46d49bf..6c50b8d 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,4 @@
Git is a version control system.
Git is free software.
+
+add more @1st
后面就是相同的步骤:
- 用
git add
添加,这时用git status
查看的话,可以知道将被提交的修改包括readme.txt
utane@ubuntu:~/learngit$ git add readme.txt
utane@ubuntu:~/learngit$ git status
ブランチ master
コミット予定の変更点:
(use "git reset HEAD <file>..." to unstage)
modified: readme.txt
- 用
git commit
提交,在git status看到仓库是干净的:
utane@ubuntu:~/learngit$ git commit -m "add more 1st"
[master 0e6ec7c] add more 1st
1 file changed, 2 insertions(+)
utane@ubuntu:~/learngit$ git status
ブランチ master
nothing to commit, working tree clean
2.1 版本回退
现在我们接着修改,然后add,commit,这样就有了这三个版本:
- version3:
Git is a version control system.
Git is free software.
add more @1st
add more @2nd
- version2:
Git is a version control system.
Git is free software.
add more @1st
- version1:
Git is a version control system.
Git is free software.
通过git log
可以查看最近的版本:
utane@ubuntu:~/learngit$ git log
commit eb699b8393c236eabd4a0167c799e12ac70ff566 (HEAD -> master)
Author: utane <lijun.kawasaki@gmail.com>
Date: Sun Feb 17 19:59:54 2019 -0800
add more 2nd
commit 0e6ec7c49ebc91ecd9af68a5b0c5964fcbc12df2
Author: utane <lijun.kawasaki@gmail.com>
Date: Sun Feb 17 19:53:56 2019 -0800
add more 1st
commit 4568339df27afae26c50dd0d51d63c049429b6f5
Author: utane <lijun.kawasaki@gmail.com>
Date: Sun Feb 17 19:21:21 2019 -0800
wrote a readme file
上面显示的结果太繁琐,可以用git log --pretty=oneline
输出更简洁的结果:
utane@ubuntu:~/learngit$ git log --pretty=oneline
eb699b8393c236eabd4a0167c799e12ac70ff566 (HEAD -> master) add more 2nd
0e6ec7c49ebc91ecd9af68a5b0c5964fcbc12df2 add more 1st
4568339df27afae26c50dd0d51d63c049429b6f5 wrote a readme file
前面一长串的是版本号。
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb…(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100
。
- 比如我们回退到第二个版本,就是上一个版本:
utane@ubuntu:~/learngit$ git reset --hard HEAD^
HEAD is now at 0e6ec7c add more 1st
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
add more @1st
输出对应文件,可以看到文件回退了。
- 另外,还可以通过版本号回退,比如:
utane@ubuntu:~/learngit$ git reset --hard 4568
HEAD is now at 4568339 wrote a readme file
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
回退到了第一个版本。
- 现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?Git提供了一个命令
git reflog
用来记录你的每一次命令,找到对应的版本号后,又可以回到最新版本了。
utane@ubuntu:~/learngit$ git reflog
4568339 (HEAD -> master) HEAD@{0}: reset: moving to 4568
0e6ec7c HEAD@{1}: reset: moving to HEAD^
eb699b8 HEAD@{2}: commit: add more 2nd
0e6ec7c HEAD@{3}: commit: add more 1st
4568339 (HEAD -> master) HEAD@{4}: commit (initial): wrote a readme file
utane@ubuntu:~/learngit$ git reset --hard eb69
HEAD is now at eb699b8 add more 2nd
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
add more @1st
add more @2nd
2.2 工作区和暂存区
Git和其他的不同之处就是有暂存区的概念。
1. 概念
工作区 working directory:
之前创建的工作目录,就是一个工作区,比如下面的learngit
目录:
utane@ubuntu:~/learngit$ ls -ah
. .. .git LICENSE readme.txt
版本库 Repository:
注意上面,还有一个隐藏目录.git
,这个不算工作区,而是Git的版本库,包含了:
- 称为stage的暂存区
- 还有Git自动创建的第一个分支 master
- 以及指向master的一个指针HEAD
utane@ubuntu:~/learngit/.git$ ls
COMMIT_EDITMSG ORIG_HEAD config hooks info objects
HEAD branches description index logs refs
之前提到将文件往Git版本库添加时,分两步:
git add
把文件添加进去,实际上就是把文件修改添加到暂存区git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支
2. 实践
- 先修改和添加文件:
- 修改之前readme.txt文件
- 添加一个新的文件LICENSE
utane@ubuntu:~/learngit$ vi readme.txt
utane@ubuntu:~/learngit$ vi LICENSE
- 用
git status
查看状态,可以看到readme.txt被修改了,而LICENSE还无法被追踪
utane@ubuntu:~/learngit$ git status
ブランチ master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
追跡されていないファイル:
(use "git add <file>..." to include in what will be committed)
LICENSE
no changes added to commit (use "git add" and/or "git commit -a")
- 用
git add
添加这两个文件后,查看状态,可以看到这两个文件都是下一次的commit对象,因为这两个文件都被放到了stage暂存区:
utane@ubuntu:~/learngit$ git add readme.txt LICENSE
utane@ubuntu:~/learngit$ git status
ブランチ master
コミット予定の変更点:
(use "git reset HEAD <file>..." to unstage)
new file: LICENSE
modified: readme.txt
- 最后用 git commit提交,查看status看到工作区是干净的了
utane@ubuntu:~/learngit$ git commit -m "uderstand stage:add license"
[master 87486c1] uderstand stage:add license
2 files changed, 3 insertions(+)
create mode 100644 LICENSE
utane@ubuntu:~/learngit$ git status
ブランチ master
nothing to commit, working tree clean
2.3 管理修改
- 在readme.txt中继续添加一行
add more @4th
utane@ubuntu:~/learngit$ vim readme.txt
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
add more @1st
add more @2nd
add more @3rd
add more @4th
- 将上面添加了
add more @4th
的文件放入暂存区:
utane@ubuntu:~/learngit$ git add readme.txt
-
继续添加行
add more @5th
,但是没有git add到暂存区。 -
将暂存区的commit:
utane@ubuntu:~/learngit$ git commit -m "git tracks changes"
[master 18de63f] git tracks changes
1 file changed, 1 insertion(+), 1 deletion(-)
这时工作区的文件,是最新的状态:
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
add more @1st
add more @2nd
add more @3rd
add more @4th
add more @5th
如果用git status查看,显示有修改没有被加到暂存区(因为第二次的 5th add more没有加到暂存区),另外暂存区没有需要commit的:
utane@ubuntu:~/learngit$ git status
ブランチ master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
2.4 撤销修改
1. 撤销工作区的修改
如果在工作区进行了修改,但是还没有git add到暂存区,使用git checkout -- file
可以丢弃工作区的修改。
- 工作区文件中追加了一行
stupid boss
utane@ubuntu:~/learngit$ vi readme.txt
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
add more @1st
add more @2nd
add more @3rd
add more @4th
stupid boss
git status
查看其状态,反应工作区有文件修改了,还没有staged
utane@ubuntu:~/learngit$ git status
ブランチ master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
git checkout -- readme.txt
将工作区的修改撤销,可以看到最后一行消失了
utane@ubuntu:~/learngit$ git checkout -- readme.txt
utane@ubuntu:~/learngit$
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
add more @1st
add more @2nd
add more @3rd
add more @4th
2. 撤销暂存区的修改
- 将readme.txt中添加一行
stupid boss
,并添加到暂存区,用git status查看,说明已经放到了暂存区,下一步可以commit。
utane@ubuntu:~/learngit$ vi readme.txt
utane@ubuntu:~/learngit$ git add readme.txt
utane@ubuntu:~/learngit$ git status
ブランチ master
コミット予定の変更点:
(use "git reset HEAD <file>..." to unstage)
modified: readme.txt
git reset HEAD readme.txt
可以把暂存区的修改撤销掉(unstage),重新放回工作区:
utane@ubuntu:~/learngit$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
- 在查看仓库状态,看到暂存区没有文件可以commit,暂存区撤销成功了。
utane@ubuntu:~/learngit$ git status
ブランチ master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
- 进一步撤销工作区,撤销之后工作区就干净了
utane@ubuntu:~/learngit$ git checkout -- readme.txt
utane@ubuntu:~/learngit$ git status
ブランチ master
nothing to commit, working tree clean
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
add more @1st
add more @2nd
add more @3rd
add more @4th
2.5 删除文件
- 添加一个文件,并commit到仓库中
utane@ubuntu:~/learngit$ vim test.txt
utane@ubuntu:~/learngit$ git add test.txt
utane@ubuntu:~/learngit$ git commit -m "add test"
[master 47757ee] add test
1 file changed, 1 insertion(+)
create mode 100644 test.txt
- 将工作区的文件删除,然后查看仓库状态,显示有修改没有反应到暂存区,即test.txt的删除动作:
utane@ubuntu:~/learngit$ rm test.txt
utane@ubuntu:~/learngit$ git status
ブランチ master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
针对上面的删除,
- 一是确实要从版本库中删除文件,那就继续用
git rm test.txt
将删除反应到暂存区,然后commit,这样就真的删除了。 - 另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本,
git checkout -- test.txt
,git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
3. 远程仓库
- 使用
ssh-keygen -t rsa -C "lijun.kawasaki@gmail.com"
创建SSH Key
utane@ubuntu:~/learngit$ ssh-keygen -t rsa -C "lijun.kawasaki@gmail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/utane/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/utane/.ssh/id_rsa.
Your public key has been saved in /home/utane/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:ECWmY0c0SRiJNzNaVc2JKHe0EtkNb3kZB8uyGzJnahM lijun.kawasaki@gmail.com
The key's randomart image is:
+---[RSA 2048]----+
| ..B@O=* .o.. |
| . X+==+o=o = |
| ++*+.. = = |
| .. o o . + |
| E = |
| B o |
| + . |
| . . |
| |
+----[SHA256]-----+
- 在用户主目录下回生成
.ssh
目录,id_ras
是私钥,id_rsa.pub
是公钥
utane@ubuntu:~/learngit$ cd ..
utane@ubuntu:~$ cd .ssh
utane@ubuntu:~/.ssh$ ls
id_rsa id_rsa.pub
utane@ubuntu:~/.ssh$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC46vQk3pMTLkqiqOJr4TCdoOas3VQWBPANSqHABc4Clu/Pzs3vlYDBOq4SzREXMuZw/Uum0y8D6VyxHDrSGkPQXFabYjdWgG/dpfLnaI2RXFlGhcVOteXTZGa5nb6rrHv+61lFqdPK7q2G35YxCVqo9/UAdGQosOHg2rqpWkpV1DedqGB/taxeENHm69+4uIXSANkZqR7CXGyrUayzZvOuOOqNyhnujpW2wtX2/LFY0jd2YuPQYMrLr8r1Zkt23xsLZ8MeYdPelkJmRF73s9DiQg6fNRu+39nbXY5fAyjo1+kArfTqoxthx3a65nEu0ysexyUBV4swKLATYon/lWcp lijun.kawasaki@gmail.com
- 将上面的SSH 公钥,添加到GitHub中
3.1 添加远程库
- 登录Github,右上角“Create a new repo”按钮,添加一个新的仓库
learngit
…or create a new repository on the command line
echo "# learngit" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/utanesuke0612/learngit.git
git push -u origin master
…or push an existing repository from the command line
git remote add origin https://github.com/utanesuke0612/learngit.git
git push -u origin master
- 根据上面的提示,将本地的仓库与之关联:
添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
utane@ubuntu:~/learngit$ git remote add origin https://github.com/utanesuke0612/learngit.git
- 就可以把本地库的所有内容推送到远程库上:
utane@ubuntu:~/learngit$ git push -u origin master
Username for 'https://github.com': utanesuke0612
Password for 'https://utanesuke0612@github.com':
Enumerating objects: 20, done.
Counting objects: 100% (20/20), done.
Delta compression using up to 2 threads
Compressing objects: 100% (15/15), done.
Writing objects: 100% (20/20), 1.53 KiB | 785.00 KiB/s, done.
Total 20 (delta 6), reused 0 (delta 0)
remote: Resolving deltas: 100% (6/6), done.
To https://github.com/utanesuke0612/learngit.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
从现在起,只要本地作了提交,就可以通过命令:
$ git push origin master
把本地master分支的最新修改推送至GitHub,现在,你就拥有了真正的分布式版本库!
3.2 从远程库克隆
还有一种case,如果是现有远程库,那如何将远程库克隆到本地呢,
假设我们创建了一个新的仓库udacity
,下面用命令git clone https://github.com/utanesuke0612/udacitystudy.git
克隆一个到本地
utane@ubuntu:~$ git clone https://github.com/utanesuke0612/udacitystudy.git
Cloning into 'udacitystudy'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
utane@ubuntu:~$ ls
devlj udacitystudy デスクトップ ピクチャ
examples.desktop ダウンロード ドキュメント ミュージック
learngit テンプレート ビデオ 公開
4. 分支管理
4.1 创建与合并分支
版本回退中,我们知道每次提交,Git都把他们串成一条时间线,这条时间线就是一个分支。截止目前,这个分支就是主分支,即master分支,现在HEAD严格来说是指向master的,master才是指向提交的。
每次提交,master分支都会向前移动一步,如下图:
当我们创建新的分支,比如dev时,git新建一个指针dev,指向master相同的提交,再把head指向dev,就表示当前分支在dev上。
1. 分支操作过程
如下图,分支创建/切换 -> 分支上修改提交 -> 分支合并 -> 分支删除
2. 示例代码
- 首先创建dev分支,然后切换到dev分支
git checkout -b dev
后面使用了参数
-b
表示创建并切换,相当于git branch dev
和git checkout dev
。
utane@ubuntu:~/learngit$ git checkout -b dev
Switched to a new branch 'dev'
- 用
git branch
命令查看当前分支,看到当前是dev分支:
utane@ubuntu:~/learngit$ git branch
* dev
master
- 在当前分支上新建文件,并添加后提交:
utane@ubuntu:~/learngit$ vi dev.txt
utane@ubuntu:~/learngit$ git add dev.txt
utane@ubuntu:~/learngit$ git commit -m "test branch dev"
[dev 40ae6e5] test branch dev
1 file changed, 3 insertions(+)
create mode 100644 dev.txt
- 可以看到下面多了一个文件
utane@ubuntu:~/learngit$ ls
LICENSE dev.txt readme.txt
git checkout master
切换到master上,master中没有改文件
utane@ubuntu:~/learngit$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
utane@ubuntu:~/learngit$ ls
LICENSE readme.txt
git merge dev
将dev分支合并到当前的master上
utane@ubuntu:~/learngit$ git merge dev
Updating d720cf6..40ae6e5
Fast-forward
dev.txt | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 dev.txt
git branch -d dev
将dev分支删除
utane@ubuntu:~/learngit$ git branch -d dev
Deleted branch dev (was 40ae6e5).
utane@ubuntu:~/learngit$ git branch
* master
4.2 解决冲突
合并分支的时候,出现冲突是常见的:
- 创建一个新的分支:
utane@ubuntu:~/learngit$ git checkout -b feature1
Switched to a new branch 'feature1'
utane@ubuntu:~/learngit$ git branch
* feature1
master
- 在该分支上修改文件,并提交,
utane@ubuntu:~/learngit$ vim readme.txt
utane@ubuntu:~/learngit$ git add readme.txt
utane@ubuntu:~/learngit$ git commit -m "feature1 5th"
[feature1 44a9a3b] feature1 5th
1 file changed, 2 insertions(+)
- 切换到master分支,切换的时候会出现提示,说当前的分支比远程(origin)的分支多一次提交:
utane@ubuntu:~/learngit$ git checkout master
Switched to branch 'master'
このブランチは 'origin/master' よりも1コミット進んでいます。
(use "git push" to publish your local commits)
- 在master上也对相同的文件进行修改,并commit:
utane@ubuntu:~/learngit$ vi readme.txt
utane@ubuntu:~/learngit$ git add readme.txt
utane@ubuntu:~/learngit$ git commit -m "create new master"
[master d19476e] create new master
1 file changed, 1 insertion(+)
- 现在分支master和feature都有相同文件的修改,这种合并就可能造成冲突:
utane@ubuntu:~/learngit$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
- 果然上面冲突了,通过git status查看readme.txt存在冲突,必须手动解决后再提交。
utane@ubuntu:~/learngit$ git status
ブランチ master
このブランチは 'origin/master' よりも2コミット進んでいます。
(use "git push" to publish your local commits)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
- 可以直接查看 readme.txt文件,手动修改,Git用
<<<<<<<
,=======
,>>>>>>>
标记出不同分支的内容,
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
add more @1st
add more @2nd
add more @3rd
add more @4th
<<<<<<< HEAD
creating a new branch @master 5th
=======
Createing new branch is quick @feature 5th
>>>>>>> feature1
- 修改后,再提交:
utane@ubuntu:~/learngit$ vi readme.txt
utane@ubuntu:~/learngit$ cat readme.txt
Git is a version control system.
Git is free software.
add more @1st
add more @2nd
add more @3rd
add more @4th
creating a new branch @master 5th
Createing new branch is quick @feature 5th
utane@ubuntu:~/learngit$ git add readme.txt
utane@ubuntu:~/learngit$ git branch
feature1
* master
utane@ubuntu:~/learngit$ git commit -m "conflict fixed"
[master e0efded] conflict fixed
utane@ubuntu:~/learngit$ git status
ブランチ master
このブランチは 'origin/master' よりも4コミット進んでいます。
(use "git push" to publish your local commits)
nothing to commit, working tree clean
4.3 分支管理策略
通常合并分支的时候,Git会用 Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
通过--no-ff
方式进行git merge的话,git会在merge上再生成一个新的commit,这样,从分支历史上就可以看出分支信息:
- 新建并切换到分支 dev上
utane@ubuntu:~/learngit$ git checkout -b dev
Switched to a new branch 'dev'
utane@ubuntu:~/learngit$ ls
LICENSE dev.txt readme.txt
- 修改文件并提交:
utane@ubuntu:~/learngit$ vim readme.txt
utane@ubuntu:~/learngit$ git add readme.txt
utane@ubuntu:~/learngit$ git commit -m "add merge"
[dev d64b13e] add merge
1 file changed, 2 insertions(+)
- 切换到master上,并合并dev:
git merge --no-ff -m "merge with no-ff" dev
因为本次合并要创建一个新的commit,所以加上
-m
参数,把commit描述写进去。
utane@ubuntu:~/learngit$ git checkout master
Switched to branch 'master'
このブランチは 'origin/master' よりも4コミット進んでいます。
(use "git push" to publish your local commits)
utane@ubuntu:~/learngit$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
readme.txt | 2 ++
1 file changed, 2 insertions(+)
- 通过
git log --graph --pretty=oneline --abbrev-commit
查看分支历史
utane@ubuntu:~/learngit$ git log --graph --pretty=oneline --abbrev-commit
* ca3e8c5 (HEAD -> master) merge with no-ff
|\
| * d64b13e (dev) add merge
|/
* e0efded conflict fixed
|\
| * 44a9a3b feature1 5th
* | d19476e create new master
|/
* 40ae6e5 test branch dev
* d720cf6 (origin/master) delete test
* 47757ee add test
* 18de63f git tracks changes
* 87486c1 uderstand stage:add license
* eb699b8 add more 2nd
* 0e6ec7c add more 1st
* 4568339 wrote a readme file
4.4 Bug分支
软件开发中,bug是常有的,如果我现在的dev分支中开发新功能,但是突然来了一个bug,而dev中的新功能还没有提交。 这时针对这个bug,可以通过一个新的临时分支来修复,修复后,合并分支,并将这个bug分支删除即可。
- 比如下面,我在dev分支下,暂存区的文件还没有提交:
utane@ubuntu:~/learngit$ git checkout dev
Switched to branch 'dev'
utane@ubuntu:~/learngit$ git branch
* dev
master
utane@ubuntu:~/learngit$ git status
ブランチ dev
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
- Git还提供了一个
stash
功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作.
utane@ubuntu:~/learngit$ git stash
Saved working directory and index state WIP on dev: d64b13e add merge
- 然后查看工作区,就是干净的了,可以放心创建新的分支修复bug。
utane@ubuntu:~/learngit$ git status
ブランチ dev
nothing to commit, working tree clean
- 首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支:
utane@ubuntu:~/learngit$ git checkout master
Switched to branch 'master'
このブランチは 'origin/master' よりも6コミット進んでいます。
(use "git push" to publish your local commits)
utane@ubuntu:~/learngit$ git checkout -b issue-101
Switched to a new branch 'issue-101'
- bug修复,并提交:
utane@ubuntu:~/learngit$ vim readme.txt
utane@ubuntu:~/learngit$
utane@ubuntu:~/learngit$ git add readme.txt
utane@ubuntu:~/learngit$ git commit -m "fix bug 101"
[issue-101 5508d90] fix bug 101
1 file changed, 1 insertion(+)
- 切换到master分支,并将bug分支merge进来:
utane@ubuntu:~/learngit$ git checkout master
Switched to branch 'master'
このブランチは 'origin/master' よりも6コミット進んでいます。
(use "git push" to publish your local commits)
utane@ubuntu:~/learngit$ git merge --no-ff -m "merged bug fix 101" issue-101
Merge made by the 'recursive' strategy.
readme.txt | 1 +
1 file changed, 1 insertion(+)
- 最后删除bug分支
git branch -d issue-101
- 再重新切回dev分支开发新功能
utane@ubuntu:~/learngit$ git checkout dev
Switched to branch 'dev'
utane@ubuntu:~/learngit$ git status
ブランチ dev
nothing to commit, working tree clean
- 上面的命令查看到工作区是干净的,因为要工作保存到了某个地方,可以如下命令查看
utane@ubuntu:~/learngit$ git stash list
stash@{0}: WIP on dev: d64b13e add merge
- 接着就是从某个地方将保存的内容恢复了,有两种方式:
-
- 用
git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop
来删除;
- 用
-
- 用
git stash pop
,恢复的同时把stash内容也删了
- 用
-
utane@ubuntu:~/learngit$ git stash pop
ブランチ dev
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (6646bc908bea25d718fd1f3bd969d92c776b7fb5)
4.5 Feature分支
每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
- 添加一个新分支
feature-vulcan
utane@ubuntu:~/learngit$ git checkout -b feature-vulcan
M readme.txt
Switched to a new branch 'feature-vulcan'
- 添加新的功能文件,并commit到对应的新分支
utane@ubuntu:~/learngit$ vim vulcan.py
utane@ubuntu:~/learngit$
utane@ubuntu:~/learngit$ git add vulcan.py
utane@ubuntu:~/learngit$ git commit -m "new feature vulcan"
[feature-vulcan 44240ba] new feature vulcan
1 file changed, 1 insertion(+)
create mode 100644 vulcan.py
- 然后切换到当前的dev开发分支
utane@ubuntu:~/learngit$ git checkout dev
M readme.txt
Switched to branch 'dev'
- 这时如果功能取消,不需要合并了,那需要将分支删除,如果是
-d
的话,提示该分支没有被合并,强制删除的话,需要用-D
utane@ubuntu:~/learngit$ git branch -d feature-vulcan
error: The branch 'feature-vulcan' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-vulcan'.
utane@ubuntu:~/learngit$ git branch -D feature-vulcan
Deleted branch feature-vulcan (was 44240ba).
utane@ubuntu:~/learngit$
4.6 多人协作
当从远程仓库克隆时,实际上Git自动把本地master和远程master对应起来了,远程仓库默认名称是origin。
要查看远程信息用git remote
,更详细信息用git remote -v
:
utane@ubuntu:~/learngit$ git remote
origin
utane@ubuntu:~/learngit$ git remote -v
origin https://github.com/utanesuke0612/learngit.git (fetch)
origin https://github.com/utanesuke0612/learngit.git (push)
utane@ubuntu:~/learngit$
1. 推送分支 git push origin dev
utane@ubuntu:~/learngit$ git push origin master
utane@ubuntu:~/learngit$ git push origin dev
master是主分支,需要时刻同步,dev是开发分支也需要时刻同步,而bug和feature分支就不一定需要推送了。
2. 抓取分支
在另一台windows电脑上,克隆一个Github上相同的仓库learngit到本地:
- 克隆
git clone https://github.com/utanesuke0612/learngit.git
utane@LAPTOP-4KOGTOIU MINGW64 ~/OneDrive/Git
$ pwd
/c/Users/utane/OneDrive/Git
utane@LAPTOP-4KOGTOIU MINGW64 ~/OneDrive/Git/learngit
$ git clone https://github.com/utanesuke0612/learngit.git
Cloning into 'learngit'...
remote: Enumerating objects: 40, done.
remote: Counting objects: 100% (40/40), done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 40 (delta 19), reused 39 (delta 18), pack-reused 0
Unpacking objects: 100% (40/40), done.
- 默认情况下,只能看到本地的master分支,可以用
git branch
查看:
utane@LAPTOP-4KOGTOIU MINGW64 ~/OneDrive/Git/learngit
$ git branch
* master
- 要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是用命令创建本地dev分支:
git checkout -b dev origin/dev
utane@LAPTOP-4KOGTOIU MINGW64 ~/OneDrive/Git/learngit (master)
$ git checkout -b dev origin/dev
Switched to a new branch 'dev'
Branch dev set up to track remote branch dev from origin.
utane@LAPTOP-4KOGTOIU MINGW64 ~/OneDrive/Git/learngit (dev)
$ git branch
* dev
master
- 然后在该分支上开发,并将dev分支push到远程
git push origin dev
:
utane@LAPTOP-4KOGTOIU MINGW64 ~/OneDrive/Git/learngit (dev)
$ vi win10dev.txt
utane@LAPTOP-4KOGTOIU MINGW64 ~/OneDrive/Git/learngit (dev)
$ git add win10dev.txt
warning: LF will be replaced by CRLF in win10dev.txt.
The file will have its original line endings in your working directory.
utane@LAPTOP-4KOGTOIU MINGW64 ~/OneDrive/Git/learngit (dev)
$ git commit -m "add file from win10"
[dev f8f59b3] add file from win10
1 file changed, 1 insertion(+)
create mode 100644 win10dev.txt
utane@LAPTOP-4KOGTOIU MINGW64 ~/OneDrive/Git/learngit (dev)
$ git push origin dev
fatal: HttpRequestException encountered.
▒▒▒̗v▒▒▒̑▒▒M▒▒▒ɃG▒▒▒[▒▒▒▒▒▒▒▒▒܂▒▒▒▒B
Username for 'https://github.com': utanesuke0612
wanCounting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 282 bytes | 282.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/utanesuke0612/learngit.git
d64b13e..f8f59b3 dev -> dev
3. 解决冲突
如果你的同事在window机器上,修改并push了dev.txt,但是你linux本地没有反映到最新的,并继续在旧版本上修改:
- 修改并提交dev.txt文件
utane@ubuntu:~/learngit$ cat dev.txt
itet
test
utane@ubuntu:~/learngit$ vi dev.txt
utane@ubuntu:~/learngit$
utane@ubuntu:~/learngit$
utane@ubuntu:~/learngit$ git add dev.txt
utane@ubuntu:~/learngit$ git commit -m "conflict"
[dev 7153e6a] conflict
1 file changed, 2 insertions(+)
- 试着提交的时候,显示文件有冲突无法合并,需要先
git pull
如果 git pull 失败,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接,
git branch --set-upstream-to=origin/dev dev
utane@ubuntu:~/learngit$ git push origin dev
Username for 'https://github.com': utanesuke0612
Password for 'https://utanesuke0612@github.com':
To https://github.com/utanesuke0612/learngit.git
! [rejected] dev -> dev (fetch first)
error: failed to push some refs to 'https://github.com/utanesuke0612/learngit.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
- 使用git pull后,提示发生了冲突,需要手动解决
utane@ubuntu:~/learngit$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/utanesuke0612/learngit
f8f59b3..572f4f7 dev -> origin/dev
Auto-merging dev.txt
CONFLICT (content): Merge conflict in dev.txt
Automatic merge failed; fix conflicts and then commit the result.
- 手动解决冲突后,继续 git add -> git commit -> git push origin dev远程push到github
utane@ubuntu:~/learngit$ vi dev.txt
utane@ubuntu:~/learngit$ cat dev.txt
itet
test
confilict multi@linux 1st
conflict multi@wind 1st
utane@ubuntu:~/learngit$ git add dev.txt
utane@ubuntu:~/learngit$ git commit -m "fix conflict"
[dev 98b8b9a] fix conflict
utane@ubuntu:~/learngit$ git push origin dev
Username for 'https://github.com': utanesuke0612
Password for 'https://utanesuke0612@github.com':
Enumerating objects: 20, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 2 threads
Compressing objects: 100% (10/10), done.
Writing objects: 100% (11/11), 1.17 KiB | 1.17 MiB/s, done.
Total 11 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), completed with 1 local object.
To https://github.com/utanesuke0612/learngit.git
572f4f7..98b8b9a dev -> dev
utane@ubuntu:~/learngit$
4.7 Rebase
廖老师的这一章讲得不是很好懂,参考官方文档-3.6 Git 分支 - 变基和Git Community Book 中文版-rebase
实际碰到这种情况再补上。
5. 标签管理
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。 tag是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。
5.1 创建标签
- 在Git中打标签非常简单,首先,切换到需要打标签的分支上:
utane@ubuntu:~/learngit$ git branch
* dev
master
utane@ubuntu:~/learngit$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
- 敲命令
git tag <name>
就可以打一个新标签,可以用命令git tag
查看所有标签:
utane@ubuntu:~/learngit$ git tag v1.0
utane@ubuntu:~/learngit$ git tag
v1.0
- 默认标签是打在最新提交的commit上的,如果要打在历史版本上怎么办:
utane@ubuntu:~/learngit$ git log --pretty=oneline --abbrev-commit
f4b6a01 (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
5508d90 fix bug 101
ca3e8c5 merge with no-ff
d64b13e add merge
e0efded conflict fixed
d19476e create new master
44a9a3b feature1 5th
40ae6e5 test branch dev
d720cf6 delete test
47757ee add test
18de63f git tracks changes
87486c1 uderstand stage:add license
eb699b8 add more 2nd
0e6ec7c add more 1st
4568339 wrote a readme file
- 通过上面的命令,找到历史版本号,使用相同命令就可以打tag
utane@ubuntu:~/learngit$ git tag v0.9 5508
utane@ubuntu:~/learngit$ git tag
v0.9
v1.0
utane@ubuntu:~/learngit$ git show v0.9
commit 5508d9008bd1c81854942237aecae918d6786e6f (tag: v0.9)
Author: utane <lijun.kawasaki@gmail.com>
Date: Mon Feb 18 02:02:13 2019 -0800
fix bug 101
diff --git a/readme.txt b/readme.txt
index c17f62d..c844ac8 100644
--- a/readme.txt
+++ b/readme.txt
@@ -9,3 +9,4 @@ creating a new branch @master 5th
Createing new branch is quick @feature 5th
no-ff @dev 5th
+fixed the bug@issue-101 6th
- 还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:
utane@ubuntu:~/learngit$ git tag -a v0.8 -m "ver0.8 released" ca3e
utane@ubuntu:~/learngit$ git tag
v0.8
v0.9
v1.0
utane@ubuntu:~/learngit$ git show v0.8
tag v0.8
Tagger: utane <lijun.kawasaki@gmail.com>
Date: Mon Feb 18 22:43:25 2019 -0800
ver0.8 released
commit ca3e8c5713bbbb6ba91da16fdc08d02a5d4bc6f2 (tag: v0.8)
Merge: e0efded d64b13e
Author: utane <lijun.kawasaki@gmail.com>
Date: Mon Feb 18 01:48:00 2019 -0800
merge with no-ff
5.2 操作标签
- 如果标签打错了,可以删除,
git tag -d v0.8
utane@ubuntu:~/learngit$ git tag -d v0.8
Deleted tag 'v0.8' (was 2132c19)
- 如果要推送某个标签到远程,使用命令
git push origin v1.0
utane@ubuntu:~/learngit$ git push origin v1.0
Username for 'https://github.com': utanesuke0612
Password for 'https://utanesuke0612@github.com':
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/utanesuke0612/learngit.git
* [new tag] v1.0 -> v1.0
- 一次性推送全部尚未推送到远程的本地标签
git push origin --tags
:
utane@ubuntu:~/learngit$ git push origin --tags
Username for 'https://github.com': utanesuke0612
Password for 'https://utanesuke0612@github.com':
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/utanesuke0612/learngit.git
* [new tag] v0.9 -> v0.9
utane@ubuntu:~/learngit$ git tag
v0.9
v1.0
- 如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
utane@ubuntu:~/learngit$ git tag -d v0.9
Deleted tag 'v0.9' (was 5508d90)
- 然后,从远程删除。删除命令也是push,但是格式如下
git push origin :refs/tags/v0.9
:
utane@ubuntu:~/learngit$ git push origin :refs/tags/v0.9
Username for 'https://github.com': utanesuke0612
Password for 'https://utanesuke0612@github.com':
To https://github.com/utanesuke0612/learngit.git
- [deleted] v0.9
utane@ubuntu:~/learngit$
6. 自定义Git
我们已经配置了user.name和user.email,实际上,Git还有很多可配置项。
比如,让Git显示颜色,会让命令输出看起来更醒目:
utane@ubuntu:~$ git config --global color.ui true
utane@ubuntu:~/learngit$ git status
ブランチ master
Your branch is up to date with 'origin/master'.
6.1 忽略特殊文件
有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦。
在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
所有配置文件可以直接在线浏览:https://github.com/github/gitignore,可以自行根据需要修改
- 添加
.gitignore
文件,并写入Desktop.ini
为被忽略文件:
utane@ubuntu:~/learngit$ vi .gitignore
utane@ubuntu:~/learngit$ git add .gitignore
utane@ubuntu:~/learngit$ git commit -m "add ignore filelist"
[master ac88632] add ignore filelist
1 file changed, 6 insertions(+)
create mode 100644 .gitignore
- 新建一个文件Desktop.ini,然后git add的话,显示无法被追加,另外提示我们可以通过
git add -f Desktop.ini
强制添加:
utane@ubuntu:~/learngit$ vi Desktop.ini
utane@ubuntu:~/learngit$ git add Desktop.ini
The following paths are ignored by one of your .gitignore files:
Desktop.ini
Use -f if you really want to add them.
- 需要找出来到底哪个规则写错了,可以用
git check-ignore
命令检查,可以看到是第二行限定了它:
utane@ubuntu:~/learngit$ git check-ignore -v Desktop.ini
.gitignore:2:Desktop.ini Desktop.ini
6.2 配置别名
通过配置别名,可以使输入简化,比如配置下面第一个命令后,输入git st
就可以与git status
一样效果了。
$ git config --global alias.st status
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch
- 撤销修改,命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区。可以简化如下:
$ git config --global alias.unstage 'reset HEAD'
$ git unstage test.py
上面就可以撤除暂存区的修改了。
- 配置一个
git last
,让其显示最后一次提交信息:
$ git config --global alias.last 'log -1'
- 还有更实用的输出log命令,直接使用
git lg
就不用记一长串命令了:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
配置Git的时候,加上--global
是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。
配置文件放哪了?每个仓库的Git配置文件都放在.git/config
文件中。
- 如果需要删除的话,直接编辑文件删除对应的alias行:
utane@ubuntu:~/learngit$ git config alias.last 'log -1'
utane@ubuntu:~/learngit$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = https://github.com/utanesuke0612/learngit.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "dev"]
remote = origin
merge = refs/heads/dev
[alias]
last = log -1
6.3 搭建Git服务器
搭建Git服务器需要准备一台运行Linux的机器,强烈推荐用Ubuntu或Debian,这样,通过几条简单的apt命令就可以完成安装。
- 安装git
utane@ubuntu:~$ sudo apt-get install git
[sudo] utane のパスワード:
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
git はすでに最新バージョン (1:2.19.1-1ubuntu1.1) です。
アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 14 個。
-
创建一个git用户,用来运行git服务
sudo adduser git
: -
创建证书登录:
收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub
文件,把所有公钥导入到/home/git/.ssh/authorized_keys
文件里,一行一个。
- 先选定一个目录
/home/srv
作为Git仓库
utane@ubuntu:/home$ sudo mkdir srv
utane@ubuntu:/home$ ls
git srv utane
- 初始化Git仓库:
sudo git init --bare sample.git
- 把owner改为git:
sudo chown -R git:git sample.git
- 禁用shell登录:
出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:
git:x:1001:1001:,,,:/home/git:/bin/bash
改为:
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
- 之后,每个登录了公钥的用户,就可以通过git clone命令来克隆远程仓库了:
$ git clone git@server:/srv/sample.git
Cloning into 'sample'...
warning: You appear to have cloned an empty repository.
7. 使用GitHub
可以把github上一个任意的项目folk到自己账号下面,然后clone到本地,如下图:
比如下面我folk了著名的pandas代码,并clone到本地:
utane@ubuntu:~/learngit$ cd ..
utane@ubuntu:~$ git clone https://github.com/utanesuke0612/pandas.git
Cloning into 'pandas'...
remote: Enumerating objects: 130880, done.
...
修改之后可以,最后在GitHub上发送一个pull Request,等待对方接受。