目录
github直接创建仓库
命令一
命令二
命令三(分支)
合并分支
抓取分支
bug分支
git fatal: 拒绝合并无关的历史的错误解决
github使用
忽略特殊文件.gitignore
#通过命令在本地创建一个Django-studey01,并推送到这个刚刚创建的远程仓库上来
echo "# Django-studey01" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin [email protected]:AaronPengwp/Django-studey01.git
git push -u origin master
#把已有的本地仓库推送到远程仓库上来
git remote add origin [email protected]:AaronPengwp/Django-studey01.git
git push -u origin master
git init 初始化
git add learning.py 把代码从工作区放入到 git 暂存区
git commit -m"说明" 把代码从暂存区存入仓库
git status 查看当前的代码修改状态
git checkout [file] 把代码从暂存区回滚到工作区
git checkout -- file
命令中的--
很重要,没有--
,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout
命令。
git reset --hard HEAD^ 回滚到上一次
git reset --hard 084fd54 回滚到指定的版本
git reflog 查看所有的操作纪录
pwp@ubuntu:Django-git$ git add learning.py
pwp@ubuntu:Django-git$ git commit -m"tow commit"
[master f1822ee] tow commit
1 file changed, 1 insertion(+), 1 deletion(-)
pwp@ubuntu:Django-git$ git status
位于分支 master
无文件要提交,干净的工作区
pwp@ubuntu:Django-git$ git log
commit f1822ee2cdc35401ea8e79eb8113c7b501679de2 (HEAD -> master)
Author: AaronPengwp <[email protected]>
Date: Sat Jan 12 21:21:08 2019 +0800
tow commit
commit 084fd54898ed35e78b3f4d9c183664b21048b051
Author: AaronPengwp <[email protected]>
Date: Sat Jan 12 21:17:55 2019 +0800
first commit
pwp@ubuntu:Django-git$ ls
learning.py README.md
pwp@ubuntu:Django-git$ git add .
pwp@ubuntu:Django-git$ ls
learning.py README.md
pwp@ubuntu:Django-git$ git status
位于分支 master
要提交的变更:
(使用 "git reset HEAD <文件>..." 以取消暂存)
修改: README.md
pwp@ubuntu:Django-git$ git --hard reset HEAD^
重置后取消暂存的变更:
M README.md
M learning.py
pwp@ubuntu:Django-git$ git status
位于分支 master
尚未暂存以备提交的变更:
(使用 "git add <文件>..." 更新要提交的内容)
(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
修改: README.md
修改: learning.py
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
pwp@ubuntu:Django-git$ cat README.md
first commit
tow commit
pwp@ubuntu:Django-git$ git checkout -- README.md
pwp@ubuntu:Django-git$ cat README.md
first commit
pwp@ubuntu:Django-git$ cat learning.py
def learn():
print("hello world!")
pwp@ubuntu:Django-git$ git checkout learning.py
pwp@ubuntu:Django-git$ cat learning.py
def learn():
pass
pwp@ubuntu:Django-git$ git reflog
084fd54 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
f1822ee HEAD@{1}: commit: tow commit
084fd54 (HEAD -> master) HEAD@{2}: commit (initial): first commit
git diff [file] 查看文件具体修改了什么内容
git log --pretty=oneline 如果嫌输出信息太多,看得眼花缭乱的
rm [file] 本地删除
git checkout -- <文件> 删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本
git add / rm [file] 提交到暂存区
git reset --hard 084fd5 就算commit 了也可以时光回流
pwp@ubuntu:Django-git$ git diff README.md
diff --git a/README.md b/README.md
index 5ec586d..59079ab 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
first commit
+hello word #之后添加的内容
pwp@ubuntu:Django-git$ git log --pretty=oneline
fd743f945363f570fc58f11c0bcad4eec7efd399 (HEAD -> master) tow commit changes
084fd54898ed35e78b3f4d9c183664b21048b051 first commit
pwp@ubuntu:Django-git$ rm learning.py
pwp@ubuntu:Django-git$ git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。
尚未暂存以备提交的变更:
(使用 "git add/rm <文件>..." 更新要提交的内容)
(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
删除: learning.py
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
pwp@ubuntu:Django-git$ ls
README.md
pwp@ubuntu:Django-git$ git add .
pwp@ubuntu:Django-git$ git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。
要提交的变更:
(使用 "git reset HEAD <文件>..." 以取消暂存)
删除: learning.py
pwp@ubuntu:Django-git$ git commit -m "remove learning.py"
[master 272e691] remove learning.py
1 file changed, 2 deletions(-)
delete mode 100644 learning.py
pwp@ubuntu:Django-git$ ls
README.md
pwp@ubuntu:Django-git$ ls
README.md
pwp@ubuntu:Django-git$ git log
commit 272e6912c5b6f3632cb4216b9c3e0c2256487108 (HEAD -> master)
Author: AaronPengwp <[email protected]>
Date: Sat Jan 12 22:28:31 2019 +0800
remove learning.py
commit fd743f945363f570fc58f11c0bcad4eec7efd399 (origin/master)
Author: AaronPengwp <[email protected]>
Date: Sat Jan 12 22:07:12 2019 +0800
tow commit changes
commit 084fd54898ed35e78b3f4d9c183664b21048b051
Author: AaronPengwp <[email protected]>
Date: Sat Jan 12 21:17:55 2019 +0800
first commit
pwp@ubuntu:Django-git$ git reset --hard 084fd5
HEAD 现在位于 084fd54 first commit
pwp@ubuntu:Django-git$ ls
learning.py README.md
pwp@ubuntu:Django-git$ cat learning.py
def learn():
pass
git checkout -b branch_name 创建并切换到该分支
git checkout branch_name 切换分支
git branch
命令查看当前分支 (当前分支前面会标一个*
号)
git remote -v 查看远程库的信息
git pull 从远程更新代码到本地
git push 把本地代码推到远程仓库
git merge branch_name 合并分支
git stash 把当前工作环境临时保存
git stash apply 恢复之前保存的临时工作
git stash list 查看临时保存的列表
git stash drop 删除当前临时保存的环境备份
git stash pop 恢复并删除临时保存和备份
pwp@ubuntu:Django-git$ git checkout -b dev
切换到一个新分支 'dev'
pwp@ubuntu:Django-git$ git branch
* dev
master
pwp@ubuntu:Django-git$ ls
learning.py README.md
pwp@ubuntu:Django-git$ vim learning.py
pwp@ubuntu:Django-git$ vim README.md
pwp@ubuntu:Django-git$ git remote
origin
pwp@ubuntu:Django-git$ git remote -v
origin [email protected]:AaronPengwp/Django-study03.git (fetch)
origin [email protected]:AaronPengwp/Django-study03.git (push)#显示了可以抓取和推送的的地址。如果没有推送权限,就看不到push的地址
pwp@ubuntu:Django-git$ cat learning.py
def learn():
print("first comiit")
print("new dev")
pwp@ubuntu:Django-git$ cat README.md
first commit
hello word
Django-study03
new dev
pwp@ubuntu:Django-git$ git checkout master
M README.md
M learning.py
切换到分支 'master'
pwp@ubuntu:Django-git$ git branch
dev
* master
pwp@ubuntu:Django-git$ cat learning.py
def learn():
print("first comiit")
print("new dev")
pwp@ubuntu:Django-git$ cat README.md
first commit
hello word
Django-study03
new dev
pwp@ubuntu:Django-git$ vim learning.py
pwp@ubuntu:Django-git$ vim README.md
pwp@ubuntu:Django-git$ git add README.md
pwp@ubuntu:Django-git$ git commit -m"tow commit"
[master 3e48fff] tow commit
1 file changed, 2 insertions(+)
pwp@ubuntu:Django-git$ git push origin master
对象计数中: 3, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (3/3), 332 bytes | 332.00 KiB/s, 完成.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:AaronPengwp/Django-study03.git
36c6535..3e48fff master -> master
pwp@ubuntu:Django-git$ git checkout dev
M learning.py
切换到分支 'dev'
pwp@ubuntu:Django-git$ git branch
* dev
master
pwp@ubuntu:Django-git$ cat README.md
first commit
hello word
Django-study03
pwp@ubuntu:Django-git$ cat learning.py
def learn():
print("first comiit")
print("new dev")
pwp@ubuntu:Django-git$ vim dev_test.py
pwp@ubuntu:Django-git$ vim README.md
pwp@ubuntu:Django-git$ cat README.md
first commit
hello word chaged dev
Django-study03
changed dev
pwp@ubuntu:Django-git$ vim learning.py
pwp@ubuntu:Django-git$ git add .
pwp@ubuntu:Django-git$ git commit -m"dev test commit"
[dev f60e009] dev test commit
3 files changed, 7 insertions(+), 2 deletions(-)
create mode 100644 dev_test.py
pwp@ubuntu:Django-git$ git push origin dev
对象计数中: 5, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (4/4), 完成.
写入对象中: 100% (5/5), 463 bytes | 463.00 KiB/s, 完成.
Total 5 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'dev' on GitHub by visiting:
remote: https://github.com/AaronPengwp/Django-study03/pull/new/dev
remote:
To github.com:AaronPengwp/Django-study03.git
* [new branch] dev -> dev
一般都是在主分支(master)里操作
pwp@ubuntu:Django-git$ git pull
当前分支没有跟踪信息。
请指定您要合并哪一个分支。
详见 git-pull(1)。
git pull <远程> <分支>
如果您想要为此分支创建跟踪信息,您可以执行:
git branch --set-upstream-to=origin/<分支> master
pwp@ubuntu:Django-git$ git branch --set-upstream-to=origin/master master
分支 'master' 设置为跟踪来自 'origin' 的远程分支 'master'。
pwp@ubuntu:Django-git$ git pull
已经是最新的。
pwp@ubuntu:Django-git$ git branch
dev
* master
pwp@ubuntu:Django-git$ git merge dev
自动合并 README.md
冲突(内容):合并冲突于 README.md
自动合并失败,修正冲突然后提交修正的结果。
pwp@ubuntu:Django-git$ git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。
您有尚未合并的路径。
(解决冲突并运行 "git commit")
(使用 "git merge --abort" 终止合并)
要提交的变更:
新文件: dev_test.py
修改: learning.py
未合并的路径:
(使用 "git add <文件>..." 标记解决方案)
双方修改: README.md
pwp@ubuntu:Django-git$ vim README.md #手动修改差异
first commit
hello word chaged dev
Django-study03
<<<<<<< HEAD
new dev
tow commit
=======
changed dev
>>>>>>> dev
pwp@ubuntu:Django-git$ cat README.md
first commit
hello word chaged dev
Django-study03
new dev
tow commit
changed dev
pwp@ubuntu:Django-git$ git add .
pwp@ubuntu:Django-git$ git commit -m"fix conflict"
[master 37ae88e] fix conflict
pwp@ubuntu:Django-git$ git push
对象计数中: 3, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (3/3), 411 bytes | 411.00 KiB/s, 完成.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:AaronPengwp/Django-study03.git
3e48fff..37ae88e master -> master
提交完成,现在dev的东西是不变,改变的是master,master已经有dev的东西了
多人协作时,大家都会往master
和dev
分支上推送各自的修改。
现在,模拟一个你的小伙伴,可以在另一台电脑(注意要把SSH Key添加到GitHub)或者同一台电脑的另一个目录下克隆:
1 2 3 4 5 6 7 |
|
当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的master
分支。不信可以用git branch
命令看看:
1 2 |
|
现在,你的小伙伴要在dev
分支上开发,就必须创建远程origin
的dev
分支到本地,于是他用这个命令创建本地dev
分支:
1 |
|
现在,他就可以在dev
上继续修改,然后,时不时地把dev
分支push
到远程:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
你的小伙伴已经向origin/dev分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull
把最新的提交从origin/dev
抓下来,然后,在本地合并,解决冲突,再推
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
git pull
也失败了,原因是没有指定本地dev
分支与远程origin/dev
分支的链接,根据提示,设置dev
和origin/dev
的链接:
1 2 |
|
再pull:
1 2 3 4 5 6 |
|
这回git pull
成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
先把dev的代码保存好
pwp@ubuntu:Django-git$ git stash
保存工作目录和索引状态 WIP on dev: f60e009 dev test commit
pwp@ubuntu:Django-git$ git checkout master
切换到分支 'master'
您的分支与上游分支 'origin/master' 一致。
pwp@ubuntu:Django-git$ ls
dev_test.py learning.py README.md
pwp@ubuntu:Django-git$ cat dev_test.py
def add():
pass
pwp@ubuntu:Django-git$ git checkout -b deb-fix-102
切换到一个新分支 'deb-fix-102'
pwp@ubuntu:Django-git$ vim dev_test.py
pwp@ubuntu:Django-git$ git status
位于分支 deb-fix-102
尚未暂存以备提交的变更:
(使用 "git add <文件>..." 更新要提交的内容)
(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
修改: dev_test.py
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
pwp@ubuntu:Django-git$ git add .
pwp@ubuntu:Django-git$ git commit -m"bug-fix102-sovled"
[deb-fix-102 d05856c] bug-fix102-sovled
1 file changed, 1 insertion(+), 1 deletion(-)
#切回到master,把bug解决之后的代码从新上传
pwp@ubuntu:Django-git$ git checkout master
已经位于 'master'
您的分支领先 'origin/master' 共 1 个提交。
(使用 "git push" 来发布您的本地提交)
pwp@ubuntu:Django-git$ ls
dev_test.py learning.py README.md
pwp@ubuntu:Django-git$ ls
dev_test.py learning.py README.md
pwp@ubuntu:Django-git$ cat dev_test.py
def add():
print("dug-fix-102")
pwp@ubuntu:Django-git$ git branch
bug-fix-101
deb-fix-102
dev
* master
pwp@ubuntu:Django-git$ git pull
已经是最新的。
pwp@ubuntu:Django-git$ cat dev_test.py
def add():
print("dug-fix-102")
pwp@ubuntu:Django-git$ git push origin master
对象计数中: 3, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 354 bytes | 354.00 KiB/s, 完成.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:AaronPengwp/Django-study03.git
37ae88e..316be2e master -> master
pwp@ubuntu:Django-git$
bug修复后回到dev分支继续写代码,前提是要先恢复之前的代码:
pwp@ubuntu:Django-git$ git checkout dev
切换到分支 'dev'
pwp@ubuntu:Django-git$ ls
dev_test.py learning.py README.md
pwp@ubuntu:Django-git$ cat dev_test.py
def add():
pass
pwp@ubuntu:Django-git$ git stash apply #恢复之前的代码
位于分支 dev
尚未暂存以备提交的变更:
(使用 "git add <文件>..." 更新要提交的内容)
(使用 "git checkout -- <文件>..." 丢弃工作区的改动)
修改: dev_test.py
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
pwp@ubuntu:Django-git$ cat dev_test.py
def add():
print("hello Aaron!")
print("hello Aaron!")
print("hello Aaron!")
pwp@ubuntu:Django-git$ git stash list
stash@{0}: WIP on dev: f60e009 dev test commit
pwp@ubuntu:Django-git$ git stash drop
丢弃了 refs/stash@{0} (6756382339c5aaa6caa30b92e721086014be06af)
pwp@ubuntu:Django-git$ git stash list
pwp@ubuntu:Django-git$
本地初始化的项目 与 github 版本不一致, 导致无法提交
pwp@ubuntu:Django-git$ git pull origin master
来自 github.com:AaronPengwp/Django-study03
* branch master -> FETCH_HEAD
fatal: 拒绝合并无关的历史
解决方法
在pull 时候, 添加–allow-unrelated-histories参数 即可.
pwp@ubuntu:Django-git$ git pull origin master --allow-unrelated-histories
来自 github.com:AaronPengwp/Django-study03
* branch master -> FETCH_HEAD
自动合并 README.md
冲突(添加/添加):合并冲突于 README.md
自动合并失败,修正冲突然后提交修正的结果。
pwp@ubuntu:Django-git$ vim README.md
pwp@ubuntu:Django-git$ git add README.md
pwp@ubuntu:Django-git$ git commit -m"合并后再上传"
[master 36c6535] 合并后再上传
pwp@ubuntu:Django-git$ git push origin master
也可以:
首先将远程仓库和本地仓库关联起来:
git branch --set-upstream-to=origin/master master
然后使用git pull整合远程仓库和本地仓库,
git pull --allow-unrelated-histories
我们一直用GitHub作为免费的远程仓库,如果是个人的开源项目,放到GitHub上是完全没有问题的。其实GitHub还是一个开源协作社区,通过GitHub,既可以让别人参与你的开源项目,也可以参与别人的开源项目。
在GitHub出现以前,开源项目开源容易,但让广大人民群众参与进来比较困难,因为要参与,就要提交代码,而给每个想提交代码的群众都开一个账号那是不现实的,因此,群众也仅限于报个bug,即使能改掉bug,也只能把diff文件用邮件发过去,很不方便。
但是在GitHub上,利用Git极其强大的克隆和分支功能,广大人民群众真正可以第一次自由参与各种开源项目了。
如何参与一个开源项目呢?比如人气极高的bootstrap项目,这是一个非常强大的CSS框架,你可以访问它的项目主页https://github.com/twbs/bootstrap,点“Fork”就在自己的账号下克隆了一个bootstrap仓库,然后,从自己的账号下clone:
1 |
|
一定要从自己的账号下clone仓库,这样你才能推送修改。如果从bootstrap的作者的仓库地址[email protected]:twbs/bootstrap.git
克隆,因为没有权限,你将不能推送修改。
Bootstrap的官方仓库twbs/bootstrap
、你在GitHub上克隆的仓库my/bootstrap
,以及你自己克隆到本地电脑的仓库,他们的关系就像下图显示的那样:
如果你想修复bootstrap的一个bug,或者新增一个功能,立刻就可以开始干活,干完后,往自己的仓库推送。
如果你希望bootstrap的官方库能接受你的修改,你就可以在GitHub上发起一个pull request。当然,对方是否接受你的pull request就不一定了。
小结
在GitHub上,可以任意Fork开源仓库;
自己拥有Fork后的仓库的读写权限;
可以推送pull request给官方仓库来贡献代码。
些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status
都会显示Untracked files ...
,有强迫症的童鞋心里肯定不爽。
好在Git考虑到了大家的感受,这个问题解决起来也很简单,在Git工作区的根目录下创建一个特殊的.gitignore
文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
不需要从头写.gitignore
文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore
忽略文件的原则是:
.class
文件;举个例子:
假设你在Windows下进行Python开发,Windows会自动在有图片的目录下生成隐藏的缩略图文件,如果有自定义目录,目录下就会有Desktop.ini
文件,因此你需要忽略Windows自动生成的垃圾文件:
1 2 3 4 |
|
然后,继续忽略Python编译产生的.pyc
、.pyo
、dist
等文件或目录:
1 2 3 4 5 6 7 |
|
加上你自己定义的文件,最终得到一个完整的.gitignore
文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
最后一步就是把.gitignore
也提交到Git,就完成了!当然检验.gitignore
的标准是git status
命令是不是说working directory clean
。
使用Windows的童鞋注意了,如果你在资源管理器里新建一个.gitignore
文件,它会非常弱智地提示你必须输入文件名,但是在文本编辑器里“保存”或者“另存为”就可以把文件保存为.gitignore
了。
有些时候,你想添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore
忽略了:
1 2 3 4 |
|
如果你确实想添加该文件,可以用-f
强制添加到Git:
1 |
|
或者你发现,可能是.gitignore
写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore
命令检查:
1 2 |
|
Git会告诉我们,.gitignore
的第3行规则忽略了该文件,于是我们就可以知道应该修订哪个规则。
示例:
pwp@ubuntu:Django-git$ vim .gitignore
.........
dev_test.py
settings.py
pwp@ubuntu:Django-git$ vim settings.py
pwp@ubuntu:Django-git$ ls
dev_test.py learning.py README.md settings.py
pwp@ubuntu:Django-git$ git add .
pwp@ubuntu:Django-git$ git commit -m "add gitignore file"
[master 89ea513] add gitignore file
1 file changed, 148 insertions(+)
create mode 100644 .gitignore
pwp@ubuntu:Django-git$ git push origin master
对象计数中: 3, 完成.
Delta compression using up to 4 threads.
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (3/3), 1.55 KiB | 1.55 MiB/s, 完成.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:AaronPengwp/Django-study03.git
316be2e..89ea513 master -> master
pwp@ubuntu:Django-git$
并没有把settings.py文件加进来,但在添加.gitignore之前已经先前存在没有影响,除非你删除了再添加
小结
.gitignore
;.gitignore
文件本身要放到版本库里,并且可以对.gitignore
做版本管理!