赞
踩
https://www.liaoxuefeng.com/wiki/896043488029600/896954074659008
选择合适的目录,通过右键git bash,创建空目录:
$ mkdir learngit
$ cd learngit
$ pwd
/d/apply/git_repository/learngit
第二步,通过git init命令把该目录变成Git可以管理的仓库:
$ git init
Initialized empty Git repository in D:/apply/git_repository/learngit/.git/
现在Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),此时当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
1. 编写一个readme.txt文件,内容随意,一定要放到learngit目录下(子目录也行),因为
这是一个Git仓库;
2. 第一步用命令git add告诉Git,把文件添加到仓库:
$ git add readme.txt
3. 第二步用命令git commit告诉Git,把文件提交到仓库:
$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
命令解释: git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好
是有意义的,这样你就能从历史记录里方便地找到改动记录。git commit命令执行成功后会告诉
你,1 file changed被改动(我们新添加的readme.txt文件);2 insertions: 插入了两
行内容(readme.txt有两行内容)。
-- 修改readme.txt文件且未添加到仓库时,使用git status命令
$ git status
On branch 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 status显示有改变,此时使用git diff查看具体修改内容
$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
Git is free software
Git中每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。
git reset --hard commit_id命令:HEAD指向的版本就是当前版本,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id可以回退到指定版本号。
$ git reset --hard 7aa2101
HEAD is now at 7aa2101 append GPL
$ git log commit 7aa21019fb04b86cdac8d4d22d5ca80b22125786 Author: LIGHT OF HOPE <1176041859@qq.com> Date: Wed Aug 5 10:02:34 2020 +0800 append GPL commit e1510a1404a3d306532d05d2be1eb6027cf2c418 Author: LIGHT OF HOPE <1176041859@qq.com> Date: Wed Aug 5 09:16:43 2020 +0800 add distributed commit 4fbcb2e36d3da92b906708431f404afccf60cb2a Author: LIGHT OF HOPE <1176041859@qq.com> Date: Mon Aug 3 22:00:05 2020 +0800 wrote a readme file
$ git reflog
7aa2101 HEAD@{0}: reset: moving to 7aa2101
e1510a1 HEAD@{1}: reset: moving to HEAD^
7aa2101 HEAD@{2}: commit: append GPL
e1510a1 HEAD@{3}: commit: add distributed
4fbcb2e HEAD@{4}: commit (initial): wrote a readme file
工作区(Working Directory):就是你在电脑里能看到的目录,比如我的learngit(git仓库)文件夹就是一个工作区。
版本库(Repository):工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库,Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
把文件往Git版本库里添加的时候,是分两步执行的:
(a)第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
(b)第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
$ git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 76d770f..a9c5755 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
-Git tracks changes.
+Git tracks changes of files.
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout – file(指定文件)。
$ git status
On branch 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
-- 撤销工作区内容的修改
$ git checkout -- readme.txt
注意:git checkout – file命令中的 --很重要,没有 --,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD < file>(指定文件),就回到了场景1,第二步按场景1操作。
-- 第一步
$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
-- 第二步
$ git checkout -- readme.txt
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
注意:git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
rm test.txt(文件名)
这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了:
$ git status
On branch 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
此时有两种选择:
(1)如果确定删除版本库中的文件,则使用命令git rm删掉,并且git commit:
-- 删除版本库中的文件
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master 8dbcce0] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
(2)另一种情况是删错了,因为版本库里还存在,所以可以很轻松地把误删的文件恢复到最新版本:
$ git reset HEAD test.txt
Unstaged changes after reset:
D test.txt
$ git checkout -- test.txt
注意:git checkout – 其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
总结:命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
-- 生成ssh key
ssh-keygen -t rsa -C "youremail@example.com"
-- 后面为指定git仓库的url地址 $ git remote add origin https://github.com/cshai-github/learngit.git -- 推送到origin远程库,下面报错是因为需要登陆git账目密码 $ git push -u origin master Fatal: HttpRequestException encountered. Username for 'https://github.com': 1176041859@qq.com Counting objects: 16, done. Delta compression using up to 8 threads. Compressing objects: 100% (11/11), done. Writing objects: 100% (16/16), 1.36 KiB | 0 bytes/s, done. Total 16 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), done. To https://github.com/cshai-github/learngit.git * [new branch] master -> master Branch master set up to track remote branch master from origin.
注意:添加后,远程库的名字就是origin,这是Git默认的叫法(如上述图片中显示的命令),也可以改成别的,但是origin这个名字一看就知道是远程库。
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
-- 第一次推送完后,以后的推送则可以简化命令
$ git push origin master
-- 在工作空间右键git bash运行如下命令
$ git clone git@github.com:cshai-github/csh_code.git
Cloning into 'csh_code'...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 16 (delta 1), reused 3 (delta 0), pack-reused 0
Receiving objects: 100% (16/16), 4.25 KiB | 0 bytes/s, done.
Resolving deltas: 100% (1/1), done.
Checking connectivity... done.
分支:类似于平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN。如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN!
分支在实际中有什么用呢? 假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。 你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
SVN与Git分支管理的区别: 其他版本控制系统如SVN等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。
但Git的分支是与众不同的,无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。
Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!
不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:
假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:
Git合并分支也很快!就改改指针,工作区内容也不变!
Git鼓励大量使用分支,相关命令如下:
查看分支:git branch(会列出所有分支,当前分支前有*号)
创建分支:git branch < name>(分支名)
切换分支:git checkout < name>或者git switch < name>
创建+切换分支:git checkout -b < name>或者git switch -c < name>
合并某分支到当前分支:git merge < name>(待合并的分支名)
删除分支:git branch -d < name>
(1)查看所有分支 $ git branch * master (2)创建dev分支 $ git branch dev (3)再次查看所有分支 $ git branch dev * master (4)第四步使用git switch报错,所有此处使用有相同功能的 $ git switch dev git: 'switch' is not a git command. See 'git --help'. (5)此时查看分支,(4)命令无效 $ git branch dev * master (6)切换到dev分支 $ git checkout dev Switched to branch 'dev' (7) $ git branch * dev master (8)修改test.txt文件并添加到暂存区 $ git add test.txt (9)提交暂存区的内容 $ git commit -m "add numer in test.txt" [dev 239e11a] add numer in test.txt 1 file changed, 1 insertion(+) (10)切换回master分支 $ git checkout master Switched to branch 'master' Your branch is up-to-date with 'origin/master'. (11)查看本地仓库test.txt文件发现没有dev分支上修改的内容或者不存在test.txt文件 $ git branch dev * master (12)将dev分支合并到当前分支master上,并查看本地仓库在test.txt文件,发现与dev分支内容一致 $ git merge dev Updating 93aaed6..239e11a Fast-forward test.txt | 1 + 1 file changed, 1 insertion(+) (13)删除dev分支 $ git branch -d dev Deleted branch dev (was 239e11a). (14) $ git branch * master
注意: 到切换分支使用git checkout < branch>,而前面讲过的撤销修改则是git checkout – < file>,同一个命令,有两种作用,确实有点令人迷惑。
实际上,切换分支这个动作,用switch更科学。因此,最新版本的Git提供了新的git switch命令来切换分支。
-- 此时进行合并时会报类似的错误 $ git merge feature1 Auto-merging readme.txt CONFLICT (content): Merge conflict in readme.txt Automatic merge failed; fix conflicts and then commit the result. 查看文件如readme.txt时出现如下内容 Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. Git tracks changes of files. <<<<<<< HEAD Creating a new branch is quick & simple. ======= Creating a new branch is quick AND simple. >>>>>>> feature1
$ git log --graph --pretty=oneline --abbrev-commit
* cf810e4 (HEAD -> master) conflict fixed
|\
| * 14096d0 (feature1) AND simple
* | 5dc6824 & simple
|/
* b17d20e branch test
* d46f35e (origin/master) remove test.txt
* b84166e add test.txt
* 519219b git tracks changes
* e43a48b understand how stage works
* 1094adb append GPL
* e475afc add distributed
* eaadf4e wrote a readme file
在实际开发中,我们应该按照几个基本原则进行分支管理:
所以,团队合作的分支看起来就像这样:
$ git status
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: hello.py
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
$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)
$ git checkout -b issue-101
Switched to a new branch 'issue-101'
$ git add readme.txt
$ git commit -m "fix bug 101"
[issue-101 4c805e2] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)
git switch master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)
$ git merge --no-ff -m "merged bug fix 101" issue-101
Merge made by the 'recursive' strategy.
readme.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git switch dev
Switched to branch 'dev'
$ git status
On branch dev
nothing to commit, working tree clean
$ git stash list
stash@{0}: WIP on dev: f52c633 add merge
$ git stash pop
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: hello.py
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
Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a)
$ git stash list
$ git branch
* dev
master
$ git cherry-pick 4c805e2
[master 1d4b803] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。
Git有commit,为什么还要引入tag?
“请把上周一的那个版本打包发布,commit号是6a5819e…”
“一串乱七八糟的数字不好找!”
如果换一个办法:
“请把上周一的那个版本打包发布,版本号是v1.2”
“好的,按照tag v1.2查找commit就行!”
所以,tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。
$ git branch
* dev
master
$ git checkout master
Switched to branch 'master'
$ git tag v1.0
$ git tag
v1.0
$ git log --pretty=oneline --abbrev-commit 12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101 4c805e2 fix bug 101 e1e9c68 merge with no-ff f52c633 add merge cf810e4 conflict fixed 5dc6824 & simple 14096d0 AND simple b17d20e branch test d46f35e remove test.txt b84166e add test.txt 519219b git tracks changes e43a48b understand how stage works 1094adb append GPL e475afc add distributed eaadf4e wrote a readme file
$ git tag v0.9 f52c633
$ git tag
v0.9
v1.0
$ git show v0.9
commit f52c63349bc3c1593499807e5c8e972b82c8f286 (tag: v0.9)
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 21:56:54 2018 +0800
add merge
diff --git a/readme.txt b/readme.txt
...
$ git tag -a v0.1 -m "version 0.1 released" 1094adb
$ git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0
$ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v0.9 -> v0.9
$ git tag -d v0.9
Deleted tag 'v0.9' (was f52c633)
$ git push origin :refs/tags/v0.9
To github.com:michaelliao/learngit.git
- [deleted] v0.9
拉区代码报错:git报错fatal: unable to access ‘https://github.com/…‘: OpenSSL SSL_read: Connection was reset, e
解决办法,解除ssl:git config --global http.sslVerify “false”
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。