如何使用Git以及GitHub

时间:2023-03-27 09:37:38

  Git在程序的版本控制上有着极大的优势,下面是简单对其的简介

Git 的特点:

  1 Snapshots, Not Differences 直接记录快照而非差异对比。

  传统的版本控制系统(version control system):(CVS, Subversion, Perforce, Bazaar, and so on)都是根据时间在base version上进行的修改

  如何使用Git以及GitHub

  Git的工作模式为记录每次commit之后的快照:

如何使用Git以及GitHub

  2 Nearly Every Operation Is Local 本地化

   离线撸代码,在线后提交

  3 Git Has Integrity 完整性

  SHA-1哈希加密,除非使用Git工具,其他的程序很难访问。防止文件丢失,损坏。Git数据库中不会保留任何文件名,只有hash值

  4 Git Generally Only Adds Data

  很难进行删除,特别是fork别人仓库时,所以尽管撸,撸错了返回前版本即可

  5 The Three States:committed, modified, and staged 

  Committed means that the data is safely stored in your local database.   已保存本地数据库

  Modified means that you have changed the file but have not committed it to your database yet.   已修改未保存

  Staged means that you have marked a modified file in its current version to go into your next commit snapshot.  将修改后的添加到下一版本快照中

  three main sections of a Git project: the Git directory, the working tree, and the staging area.

如何使用Git以及GitHub

  Git DIrectory 是程序的最新版本的展现方式,如果进行拷贝则是拷贝的此目录

  Working Tree:从Git Directory中拷贝到本地进行使用和修改的版本修改区

  staging area:暂存区域,通常情况下在Git Directory中,包含了下次要提交的数据,有时也被称为索引(index)

基本的 Git 工作流程如下:

  1. 在工作目录中修改文件。

  2. 暂存文件,将文件的快照放入暂存区域。

  3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。

Git中的命令行

  1 配置命令:初始化

  配置用户名和邮箱

$ git config --global user.name "your name"
$ git config --global user.email "your email"

  提高命令输出可读性:

$ git config --global color.ui auto

  配置编辑器:

$ git config --global core.editor  emacs

  2 创建仓库

  创建一个空目录:

$ mkdir learngit
$ cd learngit
$ pwd
pwd用于展示当前路径。

  尽量避免使用中文目录,以免出现未知的错误。

$ git init
Initialized empty Git repository in “当前目录”

  第一个仓库就创建好了,会提示已生成一个空仓库,会在该目录下生成一个.git文件,默认隐藏。

  添加文件进仓库:大象放冰箱

   1 打开冰箱门:在当前目录下新建一个test1.txt文件,内容写上(请注意不要使用微软自带的记事本,推荐notepad++或Ultraedit working Directory

Git is a version control system.
Git is free software.

  2 放进大象:git add  Stage

$ git add test1.txt

  3 关上冰箱门:git commit  Git DIrectory

$ git commit -m "wrote a test1 file"
[master e56ff1a] wrote a test1 file
1 file changed, 2 insertions(+)
create mode 100644 test1.txt

  如果有多个文件需要上传到git中,可将所有文件都add了之后再commit即可

  3 打开仓库  git status git add file git diff git commit -m "comments"

  现在我们修改一下之前上传的test1.txt文件,在结尾处添加:

this is some modified info.

  再输入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: test1.txt
no changes added to commit (use "git add" and/or "git commit -a"

  上面的信息表面test1已经被修改,但还未提交,可通过个git diff来查看两者的不同而看出修改的内容

$ git diff test1.txt
diff --git a/test1.txt b/test1.txt
index d8036c1..8cf2190 100644
--- a/test1.txt
+++ b/test1.txt
@@ -1,2 +1,3 @@
Git is a version control system.
-Git is free software.
\ No newline at end of file
+Git is free software.
+this is some modified info.
\ No newline at end of file

  然后再重复之前的大象流程。就可以把修改后的版本存到git中。

  最后通过   git status 获取仓库的当前状态:

$ git status
# On branch master
nothing to commit (working directory clean)

  4 版本回滚  git log

  在编程过程中会修改很多词,如果在某次修改过程中出现了错误或者想放弃这次的修改,想找到之前的版本,这里就是git的核心优势。

commit ff72da2e4c520ec8be8b1f04f4f0cdb9b8e0421c (HEAD -> master)
Author: Big_Panda <lorry.jiang@hotmail.com>
Date:   Fri Sep 29 10:34:02 2017 +0800     add one new line commit e56ff1a8511aa6d7ee42f00f0bcbd44a216f9231
Author: Big_Panda <lorry.jiang@hotmail.com>
Date: Fri Sep 29 10:14:55 2017 +0800 wrote a test1 file commit 8e4a8cdf3bebf16e59808f64fb10fc862cedb724
Author: Big_Panda <lorry.jiang@hotmail.com>
Date: Fri Sep 29 09:21:09 2017 +0800 initial project version

  从以上可以看出三个状态,创建库,写入数据,修改数据。如果想看简略信息: --pretty=oneline

git colog --pretty=oneline
ff72da2e4c520ec8be8b1f04f4f0cdb9b8e0421c (HEAD -> master) add one new line
e56ff1a8511aa6d7ee42f00f0bcbd44a216f9231 wrote a test1 file
8e4a8cdf3bebf16e59808f64fb10fc862cedb724 initial project version  

  HEAD表示当前版本,上一个版本就是HEAD^,再上一个就是HEAD^^,如果是上一百个,就是HEAD^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^,OF CAUSE NOT,可以写成HEAD~100

pc@daodao MINGW64 /D/PycharmProjects/algorithm (master)
$ git reset --hard HEAD^
HEAD is now at e56ff1a wrote a test1 file

  再打开文件,就只剩下两行了,如果回滚错了要返回去可以吗?先看看git log中还有没有之前的版本

$ git log
commit e56ff1a8511aa6d7ee42f00f0bcbd44a216f9231 (HEAD -> master)
Author: Big_Panda <lorry.jiang@hotmail.com>
Date: Fri Sep 29 10:14:55 2017 +0800 wrote a test1 file commit 8e4a8cdf3bebf16e59808f64fb10fc862cedb724
Author: Big_Panda <lorry.jiang@hotmail.com>
Date: Fri Sep 29 09:21:09 2017 +0800 initial project version

  可以看到以前的版本已经消失了,实际上HEAD就是一个指针,现在已经指到之前的状态了,原来的状态就被隐藏。

  不过只要窗口还没关闭,还是有办法回去的,我们现在来看看,每一个log都跟了一长串数字,(一串hash加密的数字)现在就是它的用武之地。

$ git reset --hard ff72da2e4c520

  数字不用输全,确保唯一即可,再看看 git log ,是不是又回去了?其实用 git reflog 查看历史记录

$ git reflog
ff72da2 (HEAD -> master) HEAD@{0}: reset: moving to ff72da2e4c520
e56ff1a HEAD@{1}: reset: moving to HEAD^
ff72da2 (HEAD -> master) HEAD@{3}: commit: add one new line
e56ff1a HEAD@{5}: commit: wrote a test1 file
8e4a8cd HEAD@{6}: commit (initial): initial project version

  最前面的数字既是保证唯一的HEAD执政对应的hash加密值

  其他操作

    撤销修改: git checkout -- file 回到git add 或最后一个git commit的版本,如果已经放到了暂存去,可以使用 git reset HEAD filename撤销

    删除: git rm      git commit

  5 远程仓库

    在GitHub中创建账户

    本地使用 $ ssh-keygen -t rsa -C "youremail@example.com" 生成密钥,包括私有和公有密钥

    如何使用Git以及GitHub

    如何将本地的repository跟GitHub的同步呢?

    •  在GitHub中新建一个repository,name为test1
    • 将本地内容推送过去$ git remote add origin git@github.com:Jiangliruii/test1.git
    •  如果推送过程中出现了failed to push some refs to git错误,是因为GitHub中有README而本地没有导致的结构错误,使用$ git pull --rebase origin master进行合并

    至此你可以看到github中跟本地的内容一样了。从现在其,只要本地做了更改,都可以通过 $ git push origin master 提交。你就真正意义上拥有了分布式版本

  分支的操作:

    在很多情况下我们都需要多人进行协作,每个人负责自己的一个部分,这时如果在master主线上进行修改,会出现一些引用上的问题,那么这个时候就可以使用分支(即创建另一个不同于master的指针),每个人分别在自己的分支上进行修改。

    而Git官方也鼓励大家多使用分支,在每次修改之前都尽量在分支上进行修改,然后在合并到主线中,因为只是指针的移动,所以速度很快,跟直接在主线操作并无两样,但是会提高一定的安全性

    分支基本的操作指令有:

查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>

创建+切换分支:git checkout -b <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>

  某些情况会导致冲突,比如两个分支同时修改了一个文件需要merge的话就会出现冲突,git无法判定合并规则,但是使用merge命令会自动给你生成一个如下的排序

<<<<<<< HEAD      
this is branch master
=======
I change the branch already
>>>>>>> rabbit

  <<<<=====>>>>是Git帮我们生成的,可以由此来区分谁做了什么,达到合并的目的,之后再add--commit到master中,branch就可以删除了。

  使用 $ git log --graph 可以字符图形化的看到主支线。

$ git log --graph --pretty=oneline --abbrev-commit
* 9603dfe (HEAD -> master) fixed conflict
|\
| * 4dda0f0 (rabbit) add branch
* | e4b86f3 back master
|/
* bfd8d1d (origin/master) add one new line
* e562d9c wrote a test1 file
* e919d73 initial project version
* a25d6fe Initial commit

  那么当临时遇到bug又不能合并当前工作状态(我程序还没写完呢!)的怎么办?

    使用 git stash 暂存工作现场,相当于按一个暂停键,修复之后再输入 git stash pop  ,相当于继续

  多人协作的模式:分布式编程的核心

  1. 首先,可以试图用 git push origin branch-name 推送自己的修改;

  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用 git pull 试图合并;

  3. 如果合并有冲突,则解决冲突,并在本地提交;

  4. 没有冲突或者解决掉冲突后,再用 git push origin branch-name 推送就能成功!

  如果 git pull 提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令 git branch --set-upstream branch-name origin/branch-name

  使用 git remote -v 查看远程库信息。

  使用标签:对所做的操作进行分类或解释

  • 命令git tag <name>用于新建一个标签,默认为HEAD,也可以指定一个commit id;

  • git tag -a <tagname> -m "blablabla..."可以指定标签信息;

  • git tag -s <tagname> -m "blablabla..."可以用PGP签名标签;-s为私钥,必须有gpg

  • git show <tagname>可以看到PGP签名信息
  • 命令git tag可以查看所有标签。

  操作标签到远程库

  • 命令 git push origin <tagname> 可以推送一个本地标签;

  • 命令 git push origin --tags 可以推送全部未推送过的本地标签;

  • 命令 git tag -d <tagname> 可以删除一个本地标签;

  • 命令 git push origin :refs/tags/<tagname> 可以删除一个远程标签。

  GitHub有一个十分强大的前端开发库:Bootstrap,如果我们想为里面添加一点点代码,做出我们的努力,那么你需要做如下的工作:

  • Fork开源仓库;

  • 自己拥有Fork后的仓库的读写权限;

  • 可以推送pull request给官方仓库来贡献代码。

  记住,必须fork到自己账户下再在本地克隆,不然是上传不了你的修改的---不是你的账户,你没有权限。

  忽略文件:

    如果有些系统文件会在本地目录中生成而又不想上传的话会出现untrack的错误,虽然跟整个仓库管理并没有关键性的影响,但是有没有能够避免的方法呢?

  • 忽略某些文件时,需要编写.gitignore文件

  • .gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理!

  下面是国外大神总结的git语句

如何使用Git以及GitHub