git和github的使用教程

如何使用git这一高效代码管理工具

如何使用github这一最大的软件开源社区

1.github

1.1github简介

  1. (仓库)repository:

    项目代码的储存

    一个项目一个repository,多个项目多个repository

  2. (收藏)star:

    收藏项目,方便下次查看

  3. (复制克隆)Fork:

    把别人的仓库完整的复制一份到我的新建仓库,该fork项目独立存在

    使用者Fork开发者的一个仓库的时候,会生成一个连仓库名都一样的一个仓库

  4. (发起请求)pull request:

    当我对fork后的repository进行了修改,该更新动作可以通过pull request发起请求提交给项目拥有人审核,通过即可并入原项目

  5. (关注)watch:

    类似社交软件的关注,此时项目的新动作可以接收通知

  6. (评论)issue:

    体现同性交友平台这一基本属性

1.2github操作

文件操作

  1. create new file:
    就相当于在仓库里 touch了一个新的文件

    a. 文件名

    b. 文件内容:

    c. 表单:填写每次提交的目的(让其他开发者知道本次添加或修改的原因)

  2. 编辑和修改文件:

    a. 点击文件名可以查看该文件详细信息

    b. 点击铅笔图标可以修改文件

  3. 删除文件:

    点垃圾桶图标

    仍会保留commit,可以查看删除信息

  4. 上传文件(upload):

    选择点击或拖拽,比通过git命令行方便些

  5. 筛选查看文件(go to file):

    可以根据关键字快速匹配之前的文件

  6. 项目下载(clone): 项目下载到本地

开源项目贡献流程

  1. 提出issues

  2. pull request

    a. fork项目

    b. 修改自己仓库的项目代码

    c. 新建pull request

    d. 等待项目管理员审核

1.3项目索引方法

通过在索引框中添加限制条件,让搜索结果更接近自己想要的项目

常用的有仓库标题,项目描述等。。

参考链接(简书):江湖必点的小菜

2.git

2.1快速安装

等官网下载完怕是要下辈子了,这里使用淘宝镜像下载

镜像资源网站

资源使用教程

6-12更新:右键找不到git bash here选项时应如何配置!!!

https://blog.csdn.net/weixin_42357048/article/details/80533571

2.2git配置(必须进行)

Git 提供了一个叫做 git config 的工具,专门用来配置或读取相应的工作环境变量。

这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:

  • /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。

  • ~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。

  • 当前项目的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。

    也即越往项目内层靠近,config的优先级越高

a.配置用户信息(必须)

1
2
$ git config --global user.name "runoob"
$ git config --global user.email test@runoob.com

如果用了 —global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。一次设置终身使用(本机)

如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 —global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。

b.差异分析工具(可选)

在解决合并冲突时使用哪种差异分析工具

$ git config --global merge.tool vimdiff

Git 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等合并工具的输出信息。

c.查看配置信息

1
2
3
4
$ git config --list
http.postbuffer=2M
user.name=runoob
user.email=test@runoob.com

2.3如何使用

a.初始化一个新的git仓库

  • 新建一个文件夹:mkdir test
  • 路径改到当前文件夹下:cd test
  • 初始化:git init(创建一个新的git仓库)

b.向仓库添加文件、文件夹

  • 向工作区创建文件:touch+文件名(test.py)
  • 将文件提交到暂存区:git add+文件名

    ​ 添加文件夹:git add +文件夹/

    ​ 添加某类型文件:git add+*.文件类型

    ​ 添加当前文件夹下全部文件(包括子目录):git add —all

  • git add命令描述:

git add -A和 git add . git add -u在功能上看似很相近,但还是存在一点差别
git add .:他会监控工作区的状态树,使用它会把工作时的所有变化提交到暂存区,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件。
git add -u :他仅监控已经被add的文件(即tracked file),他会将被修改的文件提交到暂存区。add -u
不会提交新文件(untracked file)。(git add --update的缩写)
git add -A :是上面两个功能的合集(git add --all的缩写)

c.查看仓库信息

查看当前工作区的全部文件:git ls-files

查看当前工作区的状态变化:git status

只想看工作区里哪些文件变化:git status -s

问题1:执行了git add,git status仍然clean

原因:

文件的修改日期早于最后一次的commit,此时再提交add能够检测到文件未发生改变,即不是新文件

git status监视的是工作区的变动。

问题2:git显示文件名都是数字(中文乱码)

解决:git config --global core.quotepath false

d.管理/放弃修改(status)

  • 每次修改都得git add到暂存区,不然不会commit到仓库

  • git checkout -- file可以丢弃工作区的修改 (当然包括删除文件的恢复):

    • 一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
    • 一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
  • git reset HEAD <file>可以把暂存区的修改撤销掉(unstage),重新放回工作区

  • 以git status为例:

    • 当工作区发生变化(文件内容变动),但还没有add的时候

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      $ git status
      On branch master
      Your branch is up to date with 'origin/master'.

      Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
      modified: git和github教程.md
      modified: markdown用法.md

      no changes added to commit (use "git add" and/or "git commit -a")

      可以看到git检测到了工作区的变化,但是提醒你没有staged(),没法提交!

      此时可以执行两类操作:

      1.撤销变动(慎用,会把该文件上次commit后的全部修改作废):git checkout -- file

      2.add到暂存区

    • 当你已经执行了add或者git rm -r cached .等会改变暂存区状态的操作想要撤销:

      git reset HEAD <file>

e.版本回退(commit)

每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。

  • 通过git log查看commit历史,详情见2.4,想回到过去就需要git reflog查看命令历史
  • Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新一次的commit09d1e67...,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100
    • 回溯到上1个版本:git reset --hard HEAD^
    • 回溯到上10个版本:git reset --hard HEAD~10
    • 回溯到指定版本号(往前往后都行):git reset --hard 1094a

注意:回溯历史的版本,再用git log就看不到之后的版本了,只能用git reflog

f.删除仓库文件

  • 从git中删除文件:

    1
    git rm <file>
  • 如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f:

    1
    git rm -f <file>
  • 如果把文件从暂存区域移除,但仍然希望保留在当前工作目录中,换句话说,仅是从跟踪清单中删除,使用 —cached 选项即可

    1
    2
    git rm --cached <file>
    或者:git reset HEAD <file>
  • 可以递归删除,即如果后面跟的是一个目录做为参数,则会递归删除整个目录中的所有子目录和文件:

    1
    git rm –r *

    进入某个目录中,执行此语句,会删除该目录下的所有文件和子目录。

  • 删除仓库

    rm -rf .git

g.移动或重命名一个文件、目录

以重命名为例:

1
2
3
$ git mv README  README.md
$ ls
README.md

2.4查看提交历史/比较区别

  1. git log 查看提交历史 如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Administrator@SD-20200530BSYV MINGW64 /f/a_repository (master)
$ git log
commit 09d1e67851e4740eb26786e6213dd2fe0b2d25b8 (HEAD -> master)
Author: Biongd <XV06125231@126.com>
Date: Sat Jul 11 22:56:44 2020 +0800

第二次提交

commit d01a714f5b07d4534ea705a91656e89e974cf97a (origin/master)
Author: Biongd <XV06125231@126.com>
Date: Sat Jul 11 19:59:04 2020 +0800

第一次提交

commit 3c036605e8320393b790281e9711a14d1bfcab95
Author: Biongd <67846941+Biongd@users.noreply.github.com>
Date: Sat Jul 11 20:55:30 2020 +0800

Create README.md
  1. 我们可以用 —oneline 选项来查看历史记录的简洁的版本。

    —reverse —online可以逆向显示

1
2
3
4
5
$ git log --oneline
a1da438 (HEAD -> master, origin/master) 数据结构与算法.md.
39474be 测试更新会不会产生新文件
50e69cb 提交文件
953e256 对象的理解
  1. 可以用 —graph 选项,查看历史中什么时候出现了分支、合并。以下为相同的命令,开启了拓扑图选项:

    1
    2
    3
    4
    5
    6
    7
     git log --graph
    * commit a1da438ef8cc3d075b5c0a0b8e47c94e23f60272 (HEAD -> master, origin/master)
    | Author: biongd <862991505@qq.com>
    | Date: Tue Jul 21 16:40:07 2020 +0800
    * commit a1da438ef8cc3d075b5c0a0b8e47c94e23f60272 (HEAD -> master, origin/master
    |
    | 数据结构与算法.md.
  2. git diff 比较两个commit差异

    可以看到这是从第二次提交的内容中找和第一次不同的地方

    严格来说应该是第二次提交后,分支的内容与上一次后的分支内容有哪些变化

1
2
3
4
5
6
7
8
9
10
$ git diff 39474be a1da438
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
index 093ac5b..10569c0 100644
--- "a/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
@@ -6,6 +6,7 @@ categories: 算法
---
对数据结构和算法的学习进行一下梳理,考虑后面将学习内容打印出来
+我在这也改一下看是不是仍然不更新
# 数据结构

2.5 git bash 中文显示为数字的问题

如上所示:文件名中的中文均被数字和斜杠代替,解决方法如下:

git config —global core.quotepath false//注意是2个”-“

2.6 当近端和远程发生冲突

如果是同一个分支,一般会采用 pull rebase 进行合并,即不会形成新的提交点。而默认 git pull 是通过 merge 合并。

如果发生冲突的话,无论是 merge,还是 rebase,都需要先解决冲突,这个过程需要通过手动解决。比如发现一个文件发生冲突。手动解决完冲突后,用 git add 把处理好的内容提交到暂存区。接下来的处理,merge 和 rebase 的操作不同。

如果是 merge,通过 git commit 即可。如果是 rebase,通过 git rebase —continue,继续执行 rebase 即可。

一个简单的例子。

假设 pull 之后,某个文件内容如下

1
2
3
4
5
<<<<<<< HEAD
func main() {
=======
const a = 1
>>>>>>> feature1

我们需要手动解决文件冲突,修改之后的内容如下:

1
2
const a = 1
func main() {

接着,执行 git add 把文件提交到暂存区,接着通过 git commit 提交到仓库,最后,通过 git push 提交到远程。假设是 rebase,只需要将 git commit 修改为 git rebase —continue 即可。

3.git和github远程仓库

既可以通过https协议访问github,也可以通过添加ssh key(本机秘钥)来访问,推荐使用ssh key,可以不用输入账号密码验证

3.1从远程仓库的项目克隆到本地:

git:git clone+仓库地址(https或者SSH)

3.2添加秘钥及远程库

1.添加ssh key

ssh-keygen -t rsa -C "youremail@example.com"

邮箱用处不大随便填就好,然后一路默认就行(别乱填,不然容易出错),成功的话会在C:\user\administrator下生成 .ssh 文件夹,打开 id_rsa.pub,复制里面的 key。回到github或码云的个人头像setting,找到ssh and GPG keys 粘贴进去

2.检查key有没有有效添加(能否成功连上github)

1
2
$ ssh -T git@github.com
Hi tianqixin! You've successfully authenticated, but GitHub does not provide shell access.

3.添加远程库

git remote add [shortname] [url]

3.3将本地仓库同步到git远程仓库:

1
2
3
4
5
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:Biongd/123.git
git push -u origin master

3.4查看当前的远程库

1
2
3
4
5
$ git remote
origin
$ git remote -v
origin git@github.com:tianqixin/runoob-git-test.git (fetch)
origin git@github.com:tianqixin/runoob-git-test.git (push)

3.5提取远程仓库更新

1
2
3
4
5
6
7
8
1.从远程仓库下载新分支与数据:git fetch(获取分支更新)
$ git fetch origin
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:tianqixin/runoob-git-test
0205aab..febd8ed master -> origin/master
1
2
3
4
5
6
2.从远端仓库提取数据并尝试合并到当前分支:git merge(将更新合并到本地分支)
$ git merge origin/master
Updating 0205aab..febd8ed
Fast-forward
README.md | 1 +
1 file changed, 1 insertion(+)

也可以直接用’git pull origin master’实现远程拉取

3.6将本地仓库同步到git远程仓库踩过的坑:

大坑1:ssh模式未配置导致无法通过此方式沟通远程

1
2
ERROR: Permission denied to deploy public key
fatal: Could not read from remote repository.

原因:经过查阅发现是ssh模式不支持 用户名+密码 验证,需要调整gitlab服务器ssh配置。

解决:

  1. vi /etc/ssh/sshd_config

  2. 修改这一行

  3. PasswordAuthentication no

  4. PasswordAuthentication yes

大坑2:ssh密钥部署出错

1
2
ERROR: Permission to Biongd/Spider_douban.git denied to deploy key
fatal: Could not read from remote repository.

原因:我把ssh秘钥部署到单个项目(个人博客)的deploy中去了,打开个人窗口里的setting,可以看到there is no SSH keys associated with your account。

解决:进入单个仓库的setting-deploy,将ssh删除,然后点头像-setting-SSH and GPG keys,将本地ssh添加到这里

大坑3:本地版本和远程版本不同就push

1
2
3
4
5
6
7
8
9
git push origin master
To github.com:smartBBer/LeetCode.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'git@github.com:smartBBer/LeetCode.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.

原因:本地库和GitHub中的库不同步

解决:使用git pull —rebase origin master合并 GitHub 和 本地 的库,本地会多出之前不同步的文件。

大坑4:add远程端口时报错

$ git remote add origin git@gitee.com:biongd/notebook.git fatal: remote origin already exists.

add origin相当于开了一个远端的端口,命名为origin,这个错误直接将origin删掉就可以了

解决:git rm remote origin

4.分支管理

分支管理的系统解释

项目中的实际使用

rebase和merge的区别简述

4.1 如何新建和切换分支(HEAD)

可以将每一次的commit都看成是一次变化,并当成一次历史状态储存下来,也就是所谓的版本

git checkout -b dev

=git branch(新建分支)dev + git checkout dev

6-18更新:新的切换分支方式

git switch -c dev

此时dev和master指向同一个commit,HEAD切换到dev分支上,此时如果有新的commit,则HEAD和dev都指向新的commit,master仍在原来位置

4.2 合并和删除分支(切换到master下)

master:A-B-C

dev: A-B-C-D

git merge dev (master) 把dev分支的新commit merge到master上。

master:A-B-C-D

这是建立在dev分支比master超前一个版本的基础上

如果此时master也更新了一个版本,master:A-B-C-E

再次执行git merge dev

此时master分支多出一个新的合并后版本:A-B-C-E-F(F是把D和E合并的版本)

dev仍保持不变:A-B-C-D

删除分支:git branch -d dev

4.3 —rebase

master:D-E-F-G

在E版本处分出来一个分支dev,也进行了开发:D-E-A-B-C

这时候在master下,通过变基git rebase

即给topic换了一个爹master,此时的topic的路径就变成了

D-E-F-G-A‘-B’-C‘

和之前相比相当于引入了F-G两次提交的变化

4.4 origin/master

  • git pull 与 git fetch的区别

    git pull:取回远程服务器(github)某个分支的更新,再与本地的指定分支合并。

    git pull = git fetch + git merge

    git fetch不会进行合并执行后需要手动执行git merge合并分支,而git pull拉取远程分之后直接与本地分支进行合并。更准确地说,git pull使用给定的参数运行git fetch,并调用git merge将检索到的分支头合并到当前分支中。

    语法:git pull origin master:brantest

    和rebase类似,冒号右面的可以省略,可以知道是远程服务器向本地合并

  • 知道了git pull的含义,-rebase模式也就更好理解了

    即通过换爹的方式将远程分支并入本地

    比如:

    • 本地提交(master):A-B-C-D

      push到远程(origin/mster):A-B-C-D

    • 本地又回溯到C:A-B-C

      远程:A-B-C-D

      此时已经无法push,只能通过git pull —rebase将远程拉到本地,让本地也是A-B-C-D

    • 本地再次提交E:A-B-C-E

      远程:A-B-C-D

      假设1:

      假设D和E含共同文件且该文件内容不同,此时git pull —rebase也会产生冲突

    ​ 解决方法:

    ​ 1.强制覆盖:git push -u origin master -f

    ​ 2.手动解决,然后continue

    ​ 3.abort后,修改提交历史至相同分支。然后执行git pull或git push

    假设2:

    ​ 假设D和E含共同文件但相对C的修改并不一样,也就是没有冲突

    ​ 我通过git pull —rebase origin master就能够给本地分支换个爹,

    ​ 分支变为:A-B-C-D-E’

    ​ 此时就可以push到远程,本地分支的基发生变化

总结

本地分支和远程分支就像是两个平行分支(虽然都叫master),区别只在于本地的merge操作换了种叫法

push就相当于远程分支下merge本地分支的内容

pull 就相当于本地分支下merge远程分支的内容

两台计算机和一个网络服务器就相当于三条平行分支了。。只是通过不断的pull和push来让3条分支齐头并进