Git快速上手
Linux 平台上安装
Git 的工作需要调用 curl,zlib,openssl,expat,libiconv 等库的代码,所以需要先安装这些依赖工具
在有 yum 的系统上(比如 Fedora)或者有 apt-get 的系统上(比如 Debian 体系),可以用下面的命令安装:
各 Linux 系统可以很简单多使用其安装包管理工具进行安装:
Debian/Ubuntu
Debian/Ubuntu Git 安装命令为:
apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev
apt-get install git-core
git --version
Centos/RedHat
如果你使用的系统是 Centos/RedHat 安装命令为:
yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
yum -y install git-core
git --version
Git 配置
–system 针对所有用户
–global 针对当前用户
什么都不加参数,当前项目
优先级别:当前项目>global>system
用户信息
配置个人的用户名称和电子邮件地址:
git config --global user.name ""
git config --global user.email @qq.com
查看配置信息
要检查已有的配置信息,可以使用 git config –list 命令:
git config --list
也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:
git config user.name
hsiehchou
设置ssh
[root@test ~]# ssh-keygen -t rsa -C “@qq.com”
linux环境
vi /etc/hosts
添加一行:13.229.188.59 github.com
linux下
在~/下, touch创建文件 .git-credentials, 用vim编辑此文件,输入:
vi ~/.git-credentials
https://{用户名}:@{密码}@github.com
注意去掉{}
在终端下执行 git config –global credential.helper store
可以看到~/.gitconfig文件,会多了一项:
[credential]
helper = store
Windows环境
C:\Windows\System32\drivers\etc\hosts
添加一行:13.229.188.59 github.com
Github端的操作
在Github的setting里面的SSH and GPG key的SSH keys添加公钥
公钥的获取方法是:
cat id_rsa_github.pub
连接成功
[root@test .ssh]# ssh -T git@github.com
-i ~/.ssh/id_rsa_github
使用命令
在git bash 中执行
设置记住密码(默认15分钟):
git config –global credential.helper cache
如果想自己设置时间,可以这样做:
git config credential.helper ‘cache –timeout=7200’
这样就设置l两个小时之后失效
长期存储密码:
git config –global credential.helper store
1、在git bash里边输入 git remote -v
git remote rm origin //删除http
git remote add origin git@github.com:~/~.git //添加ssh
git push origin //执行更改
[root@test ~]# mkdir test
[root@test ~]# cd test/
[root@test test]# git init
Initialized empty Git repository in /root/test/.git/
[root@test test]# vim readme.md
[root@test test]# git status
[root@test test]# git add readme.md
[root@test test]# git status
[root@test test]# vim test1
[root@test test]# git add test1
[root@test test]# git status
[root@test test]# git commit -m “first commit”
简易提交显示
oneline 将 每个提交放在一行显示
[root@test test]# git log –pretty=oneline
图示表示版本提交
[root@test test]# git log –graph
commit 8dd0b3d1a2be7064f7bb27e83a6ddc91146d38d0
| Author:
| Date:
|
| first commit
|commit 5c2519af68ea0d0746894122b51a77cd11071ab8
reset
a->b->c->d使用git reset方法回到版本c,有3种方式:
–hard
版本库:c
暂存区:c,删掉版本d的暂存区
工作区:c,删掉版本d的工作区
–sort
版本库:c
暂存区:c,保留版本d的暂存区
工作区:c,保留版本d的工作区
–mixed(默认)
版本库:c
暂存区:c,删除版本d的暂存区
工作区:回到版本c,同时保留版本d的工作区
git diff:暂存区 (比较前的文件)和工作区比较(比较后的文件)
git diff –cached:版本库(比较前的文件)和暂存区比较
git diff HEAD:版本库(比较前的文件)和工作区比较
— a/a
+++ b/a
@ -1 +1 @@
-1
+123
工作区:就是电脑上看到的目录,比如目录下test里的文件(.git隐藏目录版本库除外)。或者以后需要再新建的目录文件等等都属于工作区范畴。
版本库(Repository):工作区有一个隐藏目录.git,这个不属于工作区,这是版本库。其中版本库里面存了很多东西,其中最重要的就是stage(暂存区),还有Git为我们自动创建了第一个分支master,以及指向master的一个指针HEAD。
git add 把文件添加进去,实际上就是把文件添加到暂存区
git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支上
diff
[root@test diff]# git diff
diff –git a/a b/a (a(编辑前的版本,暂存区)/a ,b(编辑后的版本,工作区)/a
index 14cf074..ac80211 100644(两个文件的哈希值比较)
— a/a(—文件变动前的版本,暂存区)
+++ b/a(+++文件变动后的版本,工作区)
@ -1,2 +1,2 @@(-代表变动前,+代表变动后,1代表第一行,1,2代表连续两行)
-123:代表原版本
+123 4:代表变动后的版本在前版本上面的增加后的
fd
log
git reflog :查询所有的提交历史
git log:看不到commit id的删除记录
例如:
[root@test log]# git reset –hard 7677a3235b46c
HEAD is now at 7677a32 b
[root@test log]# git log
ls :显示不隐藏的文件与文件夹
ls -a:显示当前目录下的所有文件及文件夹包括隐藏的.和..等
ls -l :显示不隐藏的文件与文件夹的详细信息
ls -al :显示当前目录下的所有文件及文件夹包括隐藏的.和..等的详细信息
mkdir head
……
项目在创建的时候,git init在.git目录下有个HEAD文件,里面的内容指向了/refs/heads/master,但是没有master文件,说明没有任何提交
master
创建分支:git branch dev
切换到分支:git checkout dev
HEAD告诉我们当前在哪个分支上面,而且是哪一次提交
合并分支merge
[root@test branch]# git log –oneline
74a5c98 a
[root@test branch]# git merge feature
Updating 74a5c98..1636fd2
Fast-forward
b | 1 +
c | 1 +
d | 1 +
3 files changed, 3 insertions(+)
create mode 100644 b
create mode 100644 c
create mode 100644 d
[root@test branch]# git log –oneline
1636fd2 d
8837eb1 b
1ef174d c
74a5c98 a
创建并切换新分支
[root@test merge]# git checkout -b feature
在当前分支基础上创建新的分支
[root@test merge]# git branch hotfix feature
[root@test merge]# git branch -v
git merge (直接合并到主分支)
合并并再次提交(合并到主分支,再次提交一次)
[root@test merge]# git merge hotfix –no-ff
分支的内容合并后放到主分支里面
[root@test merge]# git merge hotfix –squash
查看本地分支
git branch -v
如果新建的项目没有任何提交,是不能创建分支的
切换分支:git checkout <branchname>
删除分支:不能再当前分区上删除当前分区
删除分支:git branch -d <branchname>
如果当前分支有提交,而没有合并,就只能使用强制删除分支
强制删除分支:git branch -D <branchname>
重命名分支:git branch -m <oldbranchname> <newbranchname>
重命名分支可以在当前分支操作
创建远程分支:git push -u origin <branchname>
拉取远程分支:git pull origin <branchname>
删除远程分支: git push origin --delete <branchname>
重命名远程分支:
1、先删除本地分支
2、重命名本地分支
3、向远程增加分支
远程分支覆盖本地分支
git pull origin master
git reset –hard FETCH_HEAD
git merge:会有清晰的提交历史
git rebase:整洁的提交历史
git rebase合并中出现冲突情况的解决
1、git rebase
2、git status
3、vim <冲突文件>
4、git add <解决完的冲突文件>
5、git status
6、git rebase –continue
情形1
开发新功能问题
解决步骤:
1、拉取远程仓库代码
git pull origin master
2、创建新的分支,并在这个分支上写代码,提交
3、将自己的代码合并到master分支
4、然后将这个master分支推送到远程master分支
例如:
[root@test newfeature]# git remote add origin git@github.com:Hsiehchou/hsiehchou001.git
[root@test newfeature]# git pull origin master
[root@test newfeature]# vim README.md
[root@test newfeature]# git add README.md
[root@test newfeature]# git commit -m “new feature develop over”
[root@test newfeature]# git checkout master
[root@test newfeature]# git push origin master
情形2
自己正在开发新代码,而且暂存区和本地仓库都有代码,在这个时候,老板说线上有个棘手的bug需要修复,自己需要停止手上的新功能开发
解决步骤:
1、git stash 将现有的暂存区和工作区的代码保留
2、然后创建新分支,修复bug
3、重新将stash里面的内容拿取出来
例如:
git checkout -b session
vim a
git add a
vim b
git status
git stash
git checkout -b hotfix
git checkout session
git stash pop
git stash –help
情形3
自己在某个分支开发代码,然后别人在 另外的分支开发代码,现在别人已经提交好了代码,然后你想要别人的某几次提交,间隔,或者某一个提交
解决步骤:
git cherry-pick 合并某一个,或者某几个提交
git cherry-pick <commit id> <commit id>
git cherry-pick <commit id>...<commit id>
合并的时候不包括左边的,但是包括右边的
[root@test cherry]# git init
Initialized empty Git repository in /root/cherry/.git/
[root@test cherry]# touch a
[root@test cherry]# git add a
[root@test cherry]# git commit -m “a”
[master (root-commit) 47f4286] a
[root@test cherry]# git checkout -b hotfix
[root@test cherry]# touch b
[root@test cherry]# git add b
[root@test cherry]# git commit -m “b”
[hotfix 1b01f55] b
[root@test cherry]# touch c
[root@test cherry]# git add c
[root@test cherry]# git commit -m “c”
[root@test cherry]# touch d
[root@test cherry]# git add d
[root@test cherry]# git commit -m “d”
[root@test cherry]# git log –oneline
45e8c64 d
cb1f9ef c
1b01f55 b
47f4286 a
[root@test cherry]# git checkout master
[root@test cherry]# git cherry-pick cb1f9ef
[root@test cherry]# git log –oneline
c00f63d c
47f4286 a
[root@test cherry]# git log –oneline
9b2ac83 d
8accef7 f
ca85346 e
c00f63d c
47f4286 a
[root@test cherry]# git checkout master
[root@test cherry]# git log –oneline
c00f63d c
47f4286 a
[root@test cherry]# git cherry-pick ca85346 9b2ac83
[root@test cherry]# git log –oneline
413b51b d
62fa796 e
c00f63d c
47f4286 a
git format-patch生成补丁
master a->b
feature a->b->c,将bc两次提交的不同生成patch给master,然后master应用补丁
远程仓库你没有权限,然后你fork远程仓库,代码,然后你clone到本地,接着修改,这是一个很小的修改,然后你又没有权限直接push到别人的仓库,这个时候你就把修改的代码生成一个patch
git format-patch <commit id>生成patch
git apply --check *.patch 检查这个patch是否能用
git am *.patch应用patch,创建git.am这个应用环境
git apply --reject *.patch会在当前文件夹下生成这个.rej,看这个.rej文件说明,去修改相应冲突的文件,修改完之后,用git add<冲突的文件>
git am --resolved
例如:
[root@test ~]# mkdir patch
[root@test ~]# cd patch/
[root@test patch]# git init
[root@test patch]# touch a
[root@test patch]# git add a
[root@test patch]# git commit -m “a”
[root@test patch]# git checkout -b feature
[root@test patch]# vim b
[root@test patch]# git add b
[root@test patch]# git commit -m “b”
[root@test patch]# vim a
[root@test patch]# git add a
[root@test patch]# git commit -m “feature a”
[root@test patch]# git log –oneline
01fd4c5 feature a
0445b79 b
ff994db a
[root@test patch]# git checkout master
[root@test patch]# vim a
[root@test patch]# git add a
[root@test patch]# git commit -m “master a”
[root@test patch]# git log –oneline
f8af4f3 master a
ff994db a
[root@test patch]# git checkout feature
[root@test patch]# git log –oneline
01fd4c5 feature a
0445b79 b
ff994db a
[root@test patch]# git format-patch –help
[root@test patch]# git format-patch ff994db
[root@test patch]# git checkout master
[root@test patch]# git apply –check 0001-b.patch
[root@test patch]# git apply –check 0002-feature-a.patch
[root@test patch]# git am *.patch
[root@test patch]# git apply 0002-feature-a.patch –reject
[root@test patch]# cat a.rej
diff a/a b/a (rejected hunks)
@ -0,0 +1 @@
+a
[root@test patch]# cat b
b
[root@test patch]# cat a
master a
[root@test patch]# vim a
[root@test patch]# git add a
[root@test patch]# git status
[root@test patch]# git am –resolved
[root@test patch]# cat a
master a
b
[root@test patch]# git status
[root@test patch]# cat a.rej
diff a/a b/a (rejected hunks)
@ -0,0 +1 @@
+a
[root@test patch]# cat a
master a
b
[root@test patch]# rm -rf a.rej
[root@test patch]# rm -rf 000*
[root@test patch]# git checkout -b hotfix
[root@test patch]# vim a
[root@test patch]# git add a
[root@test patch]# git commit -m “hotfix”
[root@test patch]# git log –oneline
1cde42d hotfix
6b1b69b feature a
8301986 b
f8af4f3 master a
ff994db a
[root@test patch]# git format-patch –help
[root@test patch]# git format-patch 6b1b69b -o /root
[root@test patch]# git checkout master
[root@test patch]# vim a
[root@test patch]# git add a
[root@test patch]# git commit -m “master2”
[root@test patch]# git apply –check /root/0001-hotfix.patch
[root@test patch]# git am /root/0001-hotfix.patch
[root@test patch]# git status
nothing to commit, working directory clean
[root@test patch]# git apply –reject /root/0001-hotfix.patch
[root@test patch]# ll
[root@test patch]# cat a.rej
diff a/a b/a (rejected hunks)
@ -1,2 +1,5 @@
master a
b
+
+hotfix
+
[root@test patch]# vim a
[root@test patch]# git add a
[root@test patch]# git am –resolved
[root@test patch]# git status