Git 个人学习笔记总结

作为程序员你还不知道 Git 和 GitHub,说不过去吧,赶紧学习一波。

一、认识 GitHub

Git 是个版本控制系统,说明白点就是进行代码的各种管理,比如你写错代码回滚啊、追寻 bug 是哪个家伙造成的啊(邪恶脸)、合并别人代码等等,达到协同进行软件的开发工作。再多说几句,版本管理控制系统分为「集中式版本控制系统」和「分布式版本控制系统」,其中很多人可能用过 SVN,就是属于集中式版本控制系统,但是 Git 属于分布式版本控制系统。关于两者区别自行搜索资料了解下。当然学习起来,Git 相对算更难上手些。

如果说单纯学习 Git 其实和 GitHub 也无关,但我觉得结合 GitHub 来学习是很好的。或许还有人还是不知道 GitHub 是什么,没关系,简单讲就是一个开源社区网站(也被大家叫为「同性恋社区」,因为活跃着基本都是程序员呀,而这个群体基本又都是 ♂ 哈哈),里面囊及了全球很多程序大牛,包括 linux 之父 Linus 也在的,并且其 linux 系统的代码也是放(即开源)在这个网站,任何人都可以查看整个源代码。对于这样一个社区网站,如果只是人人可以把代码开源于上面以让其他人也可以阅读其代码进行学习这样一个单一功能,这也太简单了吧。其实它涉及了很多了基于 Git 有关的功能,如 A 可以开源某个项目代码,别人也能克隆(即下载)下来进行阅读、修改,修改了好的功能,可以提交 A,A 觉得代码写的不错,同意请求,再进行代码合并,这样通过 n 多人一起的努力,这个项目会越来越好。这些都涉及很多 Git 有关操作,离不开的。虽然有 GUI 客户端软件操作,但是一开始学会学习使用命令行 Git 操作,这样能更好达到对 Git 的深层次学习,也有助于你更好的掌握。

这里对于如何为别人的开源的项目贡献代码,再说几句,其大概流程如下:

  1. 先点击 A 的项目仓库站点的“fork”的按钮,这样的你的 GitHub 账户下也会有一个相同的仓库;
  2. 然后把你这个 fork 过来的仓库代码 clone 检出,然后就可以进行你对该项目代码的修改了,觉得修改 ok,最后 push (即加入)到你该远程仓库,最后通过内建的“pull request”机制向项目负责人申请代码合并;
  3. A 觉得你修改的代码写的很好,就可以进行同意了,同意之后,就能把你修改的代码合并到该项目,这样你也算是为该项目贡献了力量。

不过,相信还是存在部分人可能还停留在只听过 GitHub,还没登录过该网站,更别说网站全为英文,容易失去信心,好吧,建议还是要硬着头皮先了解下这个网站吧,首先推荐下 stormzhang 写的一份 GitHub 教程,介绍的很清楚。下面几个资料也供学习:

二、Git 命令学习

2. 1 参考资料

说明:以下都是基于我看过的资料后的个人理解和总结,有些地方没表达清楚或者错误之处,还望见谅、指出。

先放出我看参考的并且认真看完的资料:

下面是我还没看待有收藏下来待看的资料(相信这些也都是讲 Git 操作而已吧,没关系,留在这,日后遇到问题了,还是可以翻翻看的):

2.2 Git 命令

限于笔者我实在文笔太烂,水平也非常有限,我就以个人最直白通俗的话来讲一讲吧。

首先 Git 属于「分布式版本控制系统」,先要好好理解这个分布式与集中式的不同。我简单说下,集中式的如 SVN,是有一台中央服务器(其实就是某台电脑安装了 svn 软件),所有开发人员从自己电脑(比如 eclipse 下安装 svn 插件)检出项目代码,任何一人修改了代码就可以提交至中央服务器,然后其他人检出(即更新、合并了代码),这样反复重复的过程,其中包括冲突的解决等,这所有的代码操作记录都记录在中央服务器 svn 中的。从中可以看出这台中央服务器的作用吧,说一个很明显的问题:万一那台中央服务器宕机了,你就不能提交,也不能更新代码了。

分布式的如 GIt,是每个人本地维护一个版本控制管理信息,怎么做到的呢?Git 啊,所以你本地需要安装 Git ,这个软件安装完毕,新建目录并在该目录下执行git init就会有一个.git隐藏文件夹及内容,这个文件夹下内容维护着该目录下的项目代码情况。但是怎么就分布式呢?——大概的,是这样,GitHub (其实就可以理解为某台电脑/服务器)上有别人提交上去的项目代码,然后你 clone (克隆/下载)来,你本地这份项目代码就包含.git文件夹,里面就有这个项目代码的版本信息,同样的,其他任何人也可以同样 clone 下来,也是有这样一份这个项目的代码提交等信息,然后你们(只要你们本地电脑都安装了 Git)都可以基于项目代码进行代码的修改了,本地就会记录你在的修改、提交、回滚等等操作信息,就算 GitHub 网站挂了也没事,你们本地都保持着这个项目代码的所有版本控制信息。 大概意思大家体会下,然后其实这里有关 Git 还有分支的概念,这个我觉得大家多去网上了解清楚。我还是说下大概意思吧,某个安卓项目为例,比如该项目有个主分支 master 是专门用来对外发布上线的代码,但是开发过程中某个节点遇到某个 bug 需要修复,则可以在此开发节点新建一个比如 hotfix 分支来进行代码的修复,修复好了再合并到主分支 master 上,然后可以删除掉 hotfix 分支。所以看得出这都会涉及很多关于 Git 命令的操作,这也是学习的重点。要学的深刻,要懂得原理和本质,但是本文只是学习记录笔记,笔者也实力有限,我只能把某些知道的点以及遇到的坑说说,更多是操作层面的阐释。但相信还是会帮助一些人的。

2.2.1 本地库常用 Git 命令

  • git init: 初始化一个目录,其实初始化完毕然后本地多出了一个 .git的隐藏目录,这个目录管理着一个代码库的版本信息。

  • git add: 把一个文件从untracked(未被追踪)状态转为到 staged状态,直白的讲,就是把文件提交到暂缓区,这个时候还没真正意义上的代码提交。格式为:git add .提交所有改动,git add hello.txt提交指定文件的改动。

  • git commit: 这步才是真正的代码提交到仓库,格式为:git commit或者加参数git commit -m “这次的提交说明信息”,前者会进入一个页面,输入 i 可以进入编辑界面,再写上这次的提交的注释说明信息(一般用来记录本次提交的主要意图),然后按 ESC键退出编辑返回到命令模式,然后连续输入两个大写的 “Z”(用 Shift 键或 Capslock 键都可以),就保存并退出了;后者的话直接可以写上提交的注释说明信息。

    如果在提交的时候出现提示设置邮箱和用户名,是为了保证提交的准确性,在提交的时候 user.name 和 user.email 会进入日志,这些信息,是追踪代码变更的关键,比如是谁修改的。以后会随更新内容一起被永久纳入历史记录。

    PS:在设置用户名的时候,可以使用任意的字符。Git 实际上是使用 email 进行关联每次提交的,只不过使用 username 作为标示符来进行显示。当你的 email 地址和 github上的 email 地址一致时,则会使用 Github 上面的 name 来进行显示。

    如果工作中只涉及一个 git 服务器,用一个全局配置就可以了。

    全局配置:

    1
    2
    3
    > git config --global user.name "strivebo"
    > git config --global user.email "ishuzb@gmail.com"
    >

    >

    非全局配置,某个项目下的配置:(去掉--global)

    1
    2
    3
    > git config user.name "strivebo"
    > git config user.email "ishuzb@gmail.com"
    >

    >

    可以使用命令来查看修改后的配置:

    1
    2
    3
    > git config --global user.name 或 git config user.name
    > git config --global user.email 或 git config user.email
    >

    >

    取消全局配置:

    1
    2
    3
    4
    5
    6
    > git config --global --unset user.name
    > git config --global --unset user.email
    >
    > git config --global user.name #(查看)全局配置账户是否已经移除
    > git config --global user.email #(查看)全局配置邮箱是否已经移除
    >
  • git reset –hard : 版本回退操作,比如我想把当前的版本回退到上一个版本,要使用什么命令呢?可以使用如下2种命令,第一种是:git reset --hard HEAD^。那么如果要回退到上上个版本只需把 HEAD^ 改成 HEAD^^ 以此类推。那如果要回退到前100个版本的话,使用上面的方法肯定不方便,我们可以使用下面的简便命令操作:git reset --hard HEAD~100 即可。

    假设: 我进行了两次修改,第一次 readme.txt 文件添加了2222,第二次添加了3333,我已经使用回退操作回到了第一次的修改,即现在文本内容为2222,但我其实又想回到第二次的修改,该怎么办呢(如何恢复3333内容呢)?这里可以:

    可以通过如下命令即可获取到版本号:git reflog,可以看到增加内容3333的版本号是多少比如为 6fcfc89,我们现在可以命令:git reset --hard 6fcfc89 来恢复了。

  • git status: 查看仓库文件状态。可以加参数 -s,即git status -s,加个 -s 用简洁模式查看当前修改和仓库里面差别多少,可以看到有多少文件被新增了,多少被修改了,多少被删除了。

  • git log: 查看提交历史记录,即版本历史信息,比如谁提交的,什么时间啊。

  • git diff: (不加选项参数)可以显示工作目录和暂存区之间的不同。换句话说,这条指令可以让你看到「如果你现在把所有文件都 add,你会向暂存区中增加哪些内容」。比如git diff develop,查看当前版本和 develop 分支的差异。

  • git diff –cached: 查看已经暂存起来的文件和上次提交的版本之间的差异。git diff –cached filename 查看已经暂存起来的某个文件和上次提交的版本之间的差异。

  • git diff –staged: 使用 git diff --staged 可以显示暂存区和上一条提交之间的不同。换句话说,这条指令可以让你看到「如果你立即输入 git commit,你将会提交什么」。

  • git branch: 查看有哪些分支,并且能看到当前处于哪个分支上。PS:初始化仓库后默认有 master 这个主分支,一般情况下不会轻易在该主分支操作。新建分支可以使用git branch <newBranch>格式,如 git branch dev新建分支 dev,其内容和和主分支一模一样。

    git branch -a:查看本地和远程所有分支

    git branch -r:查看远程所有分支

    git branch -v:查看远程分支详细信息

  • git checkout a: 切换到 a 分支。

  • git checkout -b a: 有人就说了,我要先新建再切换,未免有点麻烦,有没有一步到位的,有的:git checkout -b a 表示新建分支 a 并同时切换到分支 a。

  • git merge: 合并分支代码,比如合并 dev 分代码,需要先切换到 master 分支,再git merge dev即可合并 dev 分支代码。

  • git merge – about: 会尝试恢复到你运行合并前的状态。 但当运行命令前,在工作目录中有未储藏、未提交的修改时它不能完美处理,除此之外它都工作地很好。由于现在 Git 仓库处于冲突待解决的中间状态,所以如果你最终决定放弃这次 merge,也需要执行一次 merge –abort 来手动取消它。输入这行代码,你的 Git 仓库就会回到 merge 前的状态。

  • git branch -d: 删除分支。 假如这个分支新建错了,或者a分支的代码已经顺利合并到 master 分支来了,那么 a 分支没用了,需要删除,这个时候执行 git branch -d a 就可以把a分支删除了。

  • git branch -D: 强制删除。有些时候可能会删除失败,比如如果 a 分支的代码还没有合并到 master,你执行 git branch -d a 是删除不了的,它会智能的提示你 a 分支还有未合并的代码,但是如果你非要删除,那就执行 git branch -D a 就可以强制删除a分支。

  • git tag: 新建标签。我们在客户端开发的时候经常有版本的概念,比如 v1.0、v1.1 之类的,不同的版本肯定对应不同的代码,所以我一般要给我们的代码加上标签(即把某次提交标记为某个 tags,如 v1.0),这样假设 v1.1 版本出了一个新 bug,但是又不晓得v1.0 是不是有这个 bug,有了标签就可以顺利切换到 v1.0 的代码,重新打个包测试了。所以如果想要新建一个标签很简单,比如 git tag v1.0 就代表我在当前代码状态下新建了一个 v1.0 的标签,输入 git tag 可以查看历史 tag 记录。 想要切换到某个 tag,执行:git checkout v1.0,就可以切换到 v1.0 的代码状态。

2.2.2 操作远程仓库相关 Git 命令

  • git clone: 远程 clone 即复制/克隆一个完整的 repository (仓库,即项目代码)到本地,克隆仓库时所使用的远程主机自动被 Git 命名为origin,如果想用其他的主机名,需要用git clone命令的-o选项指定。格式为:git clone -o jQuery https://github.com/jquery/jquery.git,然后git remote命令查看,可以看到名字为远程主机名 jQuery。

    这里要特别说下,这里克隆可以有两种方式,一种 https 方式,一种 ssh 。

    1. 如果是 https 方式,复制仓库 https 地址进行 clone 操作,如:git clone https://github.com/strivebo/git-practice.git

      这样克隆下来的项目仓库,注意观察.git文件夹下的config中的文件 url:

      1
      2
      3
      4
      5
      6
      7
      >    [remote "origin"]
      > url = https://github.com/strivebo/git-practice.git
      > fetch = +refs/heads/*:refs/remotes/origin/*
      > [branch "master"]
      > remote = origin
      > merge = refs/heads/master
      >

    >

    1. 如果是 ssh 方式,复制仓库的 ssh 地址进行 clone 操作,如:git clone git@github.com:strivebo/git-practice.git

      这样克隆下来的项目仓库,注意观察.git文件夹下的config中的文件 url:

      1
      2
      3
      4
      5
      6
      7
      >    [remote "origin"]
      > url = git@github.com:strivebo/git-practice.git
      > fetch = +refs/heads/*:refs/remotes/origin/*
      > [branch "master"]
      > remote = origin
      > merge = refs/heads/master
      >

    >

    注: https 方式下 url 为 「https 地址」,shh 方式下 url 为「ssh 地址」(我就这么任性瞎说了,反正意思明白就行),所以假设你采用的 https 方式 clone 下来的项目可以通过修改这个 url 为「ssh 地址」变为了 「ssh 方式 clone 下来的」。)

    两者的区别有,若采用的 https 方式,则每次提交代码至 github 时,都要求输入 github 账号和密码才能提交,若 ssh 方式,则不需要每次的输入。但是当然在这之前,你得要添加 ssh 。

    关于 SSH 协议的历史,可以看看这篇文章:SSH 协议(Secure Shell 协议)

    这里引用我看到的网上资料关于 https 和 SSH 的区别说下:

    1、前者可以随意克隆 github上的项目,而不管是谁的;而后者则是你必须是你要克隆的项目的拥有者或管理员,且需要先添加 SSH key ,否则无法克隆。

    2、https url 在 push 的时候是需要验证用户名和密码的;而 SSH 在 push 的时候,是不需要输入用户名的,如果配置 SSH key 的时候设置了密码,则需要输入密码的,否则直接是不需要输入密码的。

    关于如何添加 ssh 我也在这里说下步骤:

    1. Linux 与 Mac 都是默认安装了 SSH ,而 Windows 系统安装了 Git Bash(即安装了 Git 就有这个) 应该也是带了 SSH 的,在终端输入ssh命令可以查看是否安装了 ssh;

    2. 紧接着输入 ssh-keygen -t rsa 或者ssh-keygen -t rsa -C "注释"格式 ,就是指定 rsa 算法生成密钥,接着连续三个回车键(不需要输入密码)然后就会生成两个文件 id_rsa 和 id_rsa.pub ,而 id_rsa 是密钥,id_rsa.pub 就是公钥。这两文件默认分别在如下目录里生成: Linux/Mac 系统 在 ~/.ssh 下,win系统在 /c/Documents and Settings/username/.ssh 下, 都是隐藏目录,大家应该能找到的;

      PS: 其实在连续安回车键中会提示输入一个密码以及确认密码,这个密码会在你提交项目时使用,如果为的话(即直接按回车键,也即未设置密码)提交项目代码时则不用输入密码;

    3. 接下来要做的是把 id_rsa.pub 的内容添加到 GitHub 上(PS:如何添加自行网上搜下,就不多说了),这样你本地的 id_rsa 密钥跟 GitHub 上的 id_rsa.pub 公钥进行配对,授权成功,这样就可以不用像 https 方式每次输入账号和密码进行验证身份才能提交了。(你就理解为,SSH 就好比进行了身份验证的这种理解。)

    4. SSH key 添加成功之后,输入 ssh -T git@github.com 进行测试,如果出现以下提示,再输入 yes 出现如下图则证明添加成功了。(图我就不截了,我觉得问题应该不大)

    对于命令 ssh-keygen添加不同参数的含义的说明可以看这篇文章: ssh-keygen参数说明

    看完该文之后,我也能解释下了。首先ssh-keygen用于为 生成、管理和转换认证密钥,包括 RSA 和 DSA 两种密钥。 密钥类型可以用 -t 选项指定。如果没有指定则默认生成用于 SSH-2 的 RSA 密钥。-c 要求修改私钥和公钥文件中的注释。本选项只支持 RSA1 密钥。程序将提示输入私钥文件名、密语(如果存在)、新注释。

  • git remote: 列出所有的远程仓库。从别处 clone 来的,默认都会有一个别名”origin”的仓库。带上 -v 可以看到具体 URL。

  • git remote add: 添加远程仓库地址。其实这些操作都是在本地,并没有实际牵涉到远程。另外 github 里面fork 过来的,默认叫”upstream”。该命令完整格式为:git remote add <主机名> <网址>,如git remote add orgin git@github.com:strivebo/git-practice.git

  • git remote rw: 删除远程仓库地址。格式为:git remote rm <主机名>

  • git remote rename: 用于远程主机的改名。完整格式为:git remote rename <原主机名> <新主机名>

  • git fetch: 一旦远程主机的版本库有了更新(Git 术语叫做 commit),需要将这些更新取回本地,这时就要用到git fetch命令。格式为:git fetch <远程主机名>,默认情况下,git fetch取回所有分支(branch)的更新。

    • 如果只想取回特定分支的更新,可以指定分支名,格式为:git fetch <远程主机名> <分支名>, 另外,所取回的更新,在本地主机上要用”远程主机名/分支名”的形式读取,比如origin主机的master,就要用origin/master读取。
    • 取回远程主机的更新以后,可以在它的基础上,使用git checkout命令创建一个新的分支,git checkout -b newBrach origin/master,该命令表示,在origin/master的基础上,创建一个新分支。此外,也可以使用git merge命令或者git rebase命令,在本地分支上合并远程分支。
  • git pull: git pull命令的作用是,取回远程主机某个分支的更新,再与本地的指定分支合并。相当于 fetch后,再进行 merge。其完整格式为:git pull <远程主机名> <远程分支名>:<本地分支名>,如取回origin主机的next分支,与本地的master分支合并,可以这样写:git pull origin next:master

    • 如果远程分支是与当前分支合并,则冒号后面的部分可以省略,即git pull origin next,该命令表示,取回origin/next分支,再与当前分支合并。实质上,这等同于先做git fetch,再做git merge

    在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动”追踪”origin/master分支。 Git也允许手动建立追踪关系。

    • git branch --set-upstream master origin/next该命令指定master分支追踪origin/next分支

    • 如果当前分支与远程分支存在追踪关系,git pull就可以省略远程分支名。git pull origin该命令表示,本地的当前分支自动与对应的origin主机”追踪分支”(remote-tracking branch)进行合并

    • 如果当前分支只有一个追踪分支,连远程主机名都可以省略,git pull该命令表示,当前分支自动与唯一一个追踪分支进行合并

    • 合并需要采用rebase模式,可以使用--rebase选项。git pull --rebase <远程主机名> <远程分支名>:<本地分支名>

    • 如果远程主机删除了某个分支,默认情况下,git pull 不会在拉取远程分支的时候,删除对应的本地分支。这是为了防止,由于其他人操作了远程主机,导致git pull不知不觉删除了本地分支。但是,你可以改变这个行为,加上参数 -p 就会在本地删除远程已经删除的分支。git pull -p 该命令等同于:

      1
      2
      3
      >   git fetch --prune origin 
      > git fetch -p
      >

    >

  • git push: git push命令用于将本地分支的更新,推送到远程主机。它的格式与git pull命令相仿。其完整格式为:git push <远程主机名> <本地分支名>:<远程分支名>

    • 如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。git push origin master该命令表示,将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。
    • 如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。git push origin :master等同于git push origin --delete master该命令表示删除origin主机的master分支。
    • 如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。git push origin该命令表示,将当前分支推送到origin主机的对应分支。
    • 如果当前分支只有一个追踪分支,那么主机名都可以省略。git push
    • 如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git pushgit push -u origin master该命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。

    备注:不带任何参数的git push,默认只推送当前分支,这叫做 simple 方式。此外,还有一种matching 方式,会推送所有有对应的远程分支的本地分支。Git 2.0版本之前,默认采用 matching 方法,现在改为默认采用 simple 方式。如果要修改这个设置,可以采用git config命令。

    1
    2
    3
    4
    > $ git config --global push.default matching
    > # 或者
    > $ git config --global push.default simple
    >

    >

    还有一种情况,就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要使用--all选项。

    1
    2
    > $ git push --all origin
    >

    >

    上面命令表示,将所有本地分支都推送到origin主机。

    如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用--force选项。

    1
    2
    > git push --force origin
    >

    >

    上面命令使用--force选项,结果导致远程主机上更新的版本被覆盖。除非你很确定要这样做,否则应该尽量避免使用--force选项。

    最后,git push不会推送标签(tag),除非使用--tags选项。git push origin --tags

关于git clonegit remotegit fetchgit pullgit push的使用是操作远程仓库最常用的命令,强烈建议去看阮一峰这篇日志文章:Git远程操作详解

三、实战学习

3.1 代码提交到 GitHub 上

  • 采用 https 方式克隆github上仓库(项目):git clone https://github.com/strivebo/git-practice.git
  • 采用 ssh 方式克隆:git clone git@github.com:strivebo/git-practice.git
  • 如果想要在克隆至本地时指定别的目录名称,可以在后面加个参数,如:git clone https://github.com/strivebo/git-practice.git git-practice-another,手动指定本地仓库的根目录名称为 git-practice-another。

在提交之前先看下这个:github中ssh和https提交的区别

从github上clone一个项目到本地的时候,有use HTTPS和use SSH两种方式,这两种主要是在push项到github上时有所不同。完成一个push操作,需要对其内容进行安全管理,这里提供了ssh和https两种方式。而在clone项目到本地时,做出选择后,就已经决定了push的方式。

ssh使用了RSA,即非对称加密的方式,存在一个公钥和私钥。可以生成一个本地的一组秘钥,然后将公钥复制到github的settings/profile下。

使用 https 方式,每次需要验证用户身份信息。

这里还有篇介绍:git使用ssh密钥和https两种认证方式汇总(转)

1、采用的是https克隆

解释下 your branch is ahead of 'origin/master' by 2 commits.

  1. Git 提示你的当前 branch 已经领先于( “ahead of” )’origin/master’ 两个提交了
  2. origin/master 的中的 origin 是远端仓库的名称,是你在用 clone 指令初始化本地仓库时 Git 自动帮你起的默认名称;master 是 origin 上的分支名称。

对于现在来说,可以暂时把 origin/master 简单理解为「中央仓库」,也就是说,这句话是告诉你,你的本地仓库已经领先中央仓库两个提交了。

然后可以使用

  • git push

    提交发布至中央服务器(这里即指 GitHub)。
    由于这是联网操作,所以在这个过程 GitHub 会再次向你索要账户和密码。填入正确的账户和密码,push 操作就完成了。这时你再去你的 GitHub 仓库页面可以看到提交记录。说明你已经成功把本地仓库的提交推送到了服务器了。

    PS:如果觉得一遍遍地输入密码很烦,可以按照这个页面 提供的方案来把密码保存起来。另外还有一个更简单但安全性低一些的方案。执行这行代码:git config credential.helper store在这之后你只需要再输入一次密码, Git 就会把你的密码保存下来,这之后就再也不用输入了。说它「安全性低」,是因为这条指令会让 Git 把你的密码以明文形式保存在你的电脑上。具体这两种保存密码的方案选择哪个,看你自己了。

总结:

  1. 从 GitHub 把中央仓库 clone 到本地(使用命令: git clone
    把写完的代码提交(先用 git add 文件名 把文件添加到暂存区,再用 git commit 提交)

  2. 在这个过程中,可以使用 git status 来随时查看工作目录的状态
    每个文件有 “changed / unstaged”(已修改), “staged”(已修改并暂存), “commited”(已提交) 三种状态,以及一种特殊状态 “untracked”(未跟踪)

  3. 提交一次或多次之后,把本地提交 push 到中央仓库(git push)…

2、采用的是ssh方式克隆

先要进行 ssh 添加。

SHH

你拥有了一个 GitHub 账号之后,就可以自由的 clone 或者下载其他项目,也可以创建自己的项目,但是你没法提交代码。仔细想想也知道,肯定不可能随意就能提交代码的,如果随意可以提交代码,那么GitHub 上的项目岂不乱了套了,所以提交代码之前一定是需要某种授权的,而 GitHub 上一般都是基于 SSH 授权的。那么什么是 SSH 呢? 简单点说,SSH是一种网络协议,用于计算机之间的加密登录。目前是每一台 Linux 电脑的标准配置。而大多数 Git 服务器都会选择使用 SSH 公钥来进行授权,所以想要在 GitHub 提交代码的第一步就是要先添加 SSH key 配置。

ssh 设置步骤:

  1. Git Bash下输入ssh出现如下则表示本机已经安装 ssh,否则自行安装下载。
  2. 紧接着输入 ssh-keygen -t rsa ,什么意思呢?就是指定 rsa 算法生成密钥,接着连续三个回
    车键(不需要输入密码) ,然后就会生成两个文件 id_rsaid_rsa.pub ,而 id_rsa 是密钥id_rsa.pub 就是公钥
    这两文件默认分别在如下目录里生成:
    Linux/Mac 系统 在 ~/.ssh 下,win系统在 /c/Documents and Settings/username/.ssh 下, 都是隐藏文件。
  3. 接下来要做的是把 id_rsa.pub 的内容添加到 GitHub 上,这样你本地的 id_rsa 密钥跟 GitHub 上的 id_rsa.pub 公钥进行配对,授权成功才可以提交代码。
  4. SSH key 添加成功之后,输入 ssh -T git@github.com 进行测试。

最后就是 pushpull的操作了。添加 SSH key 成功之后,我们就有权限向 GitHub 上我们自己的项目提交代码了!执行:git push origin master 进行代码提交。

问题: 假设我们本地有个 test2 的项目,我们需要的是在 GitHub 上建一个 test 的项目,然后把本地 test2 上的所有代码 commit 记录提交到 GitHub 上的 test 项目。

第一步就是在 GitHub 上建一个 test 项目,这个想必大家都会了,就不用多讲了。

第二步把本地 test2 项目与 GitHub 上的 test 项目进行关联,切换到 test2 目录,执行如下命
令:git remote add origin git@github.com:strivebo/test.git

什么意思呢?就是添加一个远程仓库,他的地址是 git@github.com:strivebo/test.git ,而 origin 是给这个项目的远程仓库起的名字,是的,名字你可以随便取,只不过大家公认的只有一个远程仓库时名字就是 origin ,为什么要给远程仓库取名字?因为我们可能一个项目有多个远程仓库?比如 GitHub 一个,比如公司一个,这样的话提交到不同的远程仓库就需要指定不同的仓库名字了。

查看我们当前项目有哪些远程仓库可以执行如下命令: git remote -v ,接下来,我们本地的仓库就可以向远程仓库进行代码提交了:git push origin master,就是默认向 GitHub 上的 test 目录提交了代码,而这个代码是在 master 分支。当然你可以提交到指定的分支。

两种方式的区别: git 使用 https 协议,每次 pull, push 都要输入密码,相当的烦。使用 git 协议,然后使用 ssh 密钥。这样可以省去每次都输密码。

四、问题和笔记

4.1 问题列表

问题 1:

对于前面这个「假设我们本地有个 test2 的项目,我们需要的是在 GitHub 上建一个 test 的项目,然后把本地 test2 上的所有代码 commit 记录提交到 GitHub 上的 test 项目。」情况,我在练习的时候出现了问题,错误是:fatal the current branch master has no upstream branch.

先参考这几篇文章看看:

我的总结: 如果没有配置 ssh(采用 ssh 方式),那采用以下方式:

git remote add origin https://github.com/strivebo/test.git(https方式地址克隆)

然后:(下面是引用的网上一个人的解决方式)

此时如果 origin 的 master 分支上有一些本地没有的提交,push 会失败.

所以解决的办法是, 首先设定本地master的上游分支:git branch --set-upstream-to=origin/master

然后pull:git pull --rebase

最后再push:git push

问题2:官网下载的 Git 与 TortoiseGit 客户端有什么关系吗?

  • 使用Git、Git GUI和TortoiseGit

    • Git自带GUI界面。使用 git gui 命令可以打开它。在这个界面中可以完成commit、merge、push、pull等等常用操作。

      …….

    • TortoiseGit没有集成Git。在TortoiseGit官方网站可以下载到它。有32bit和64bit版本,同时也有中文语言包(但我不建议你安装)。安装完毕之后,如果你没有安装过 Git,那么还需要去下载msysGit来安装。因为TortoiseGit其实只是一个壳,它需要调用 Git 命令行才能发挥作用。(现在你知道我为什么推荐你用命令行了么?)如果你不安装msysGit,那么在运行TortoiseGit的时候会弹出这个提示:

      为什么TortoiseGit不像TortoiseSVN一样,把SVN命令行工具集成在安装包中呢?我猜想是以下几点原因:

      • Git官方从未出过Windows版本二进制包;
      • msysGit和TortoiseGit是两个不同的团队开发的;
      • msysGit和TortoiseGit的更新周期差异较大;
      • TortoiseGit团队希望安装包更小;
      • TortoiseGit团队给用户更灵活的选择Git版本的权利。

问题3:Git 如何 clone 非 master 分支的代码?

问题描述:

在从github上clone项目下来的时候,如 https 方式克隆某个具有多个分支的项目:
git clone https://github.com/TeamNewPipe/NewPipe.git 注:该分支默认分支为 dev 分支,其他分支有 master 、multyservice 分支。

出现的问题是:克隆完毕,使用git branch查看本地分支,只能看到 dev 分支。(git branch -a可以查看到本地和远程所有分支情况。)是只能克隆到 github 项目的默认分支,其他分支没有克隆下来吗?

更具体的描述问题:

当我们想 clone 别人的在分支中修改的 code 时,我们在 github 中看到往往是 master,并且我们 clone 下来的也是也是 master,如下图,是一个工程的不同分支,当我点击不同的分支,其 clone 的 https 却是一样的,那么该如何clone我想要的分支呢?

参考的解决方式:

  • Git 如何 clone 非 master 分支的代码

    新的解决办法:先git branch -a列出本地和远程所有分支,比如某个远程分支为 origin/daily/1.4.1,然后再直接使用git checkout origin/daily/1.4.1

    旧的解决方法:1、先在本地建立与远程分支同名分支名称;2、切换到该本地分支;3、建立上游分支,即git branch --set-upstream-to=origin/daily/1.4.1 daily/1.4.1,这样完成与上游分支的关联,然后 pull 就好了。

  • 克隆Github上项目的非Master分支

    Git 默认只显示默认分支的数据,还需要手动切换到我们需要的分支并显示出来。

    1
    2
    3
    > git branch
    > git checkout -b 本地分支名字 origin/远程分支名字
    >

    >

    这样大功告成。

    这里和这篇文章 git clone远程仓库的分支 写的意思一样:

    使用 git checkout -b aaa origin/aaa。该语句作用是在本地创建新的分支,分支的名称是 aaa,aaa 也是我想要 clone 的分支的名字,这里为了便于理解将本地的分支名字和 clone 的分支名字设为一样,其实 -b 后面的 aaa 可以随意设置。

    亲测,② 的方式是 ok 的!

问题4:git pull 和 git fetch 有什么区别?

  • git pull 和 git fetch 有什么区别?

    首先,你的每一个操作都是要指明【来源】和【目标】的,而对于 pull 来说,【目标】就是当前分支;

    其次,你得清楚 git 是有 tracking 的概念的,所谓 tracking 就是把【来源】和【目标】绑定在一起,节省一些操作是需要输入的参数。

    那么,假设你的 master 和 develop 都是 tracking 了的,于是:

    • 当你在 master 下,git pull等于 fetch origin,然后 merge origin/master
    • 当你在 develop 下,git pull等于 fetch origin,然后 merge origin/develop

4.2 笔记

笔记1:在本地仓库初始化后,不进行 commit 提交,则新建不了分支;进行了commit提交,则真正建立了master 分支。

这里引用阮一峰老师的 Git 文章写的:

在某些场合,Git 会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在 git clone 的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动”追踪” origin/master 分支。Git 也允许手动建立追踪关系:git branch --set-upstream master origin/next 该命令指定 master 分支追踪 origin/next 分支。

笔记2:重命名分支及远程分支名称:

在 git 中重命名远程分支,其实就是先删除远程分支,然后重命名本地分支,再重新提交一个远程分支。

  1. 删除分支的命令是:
    在 Git1.7 之后可以使用这个命令git push origin --delete <远程分支名称>,否则用这个也可以:git push origin :<远程分支名称> 表示推送一个空分支到远程分支,其实就相当于删除远程分支。

  2. 重命名本地分支:git branch -m <旧名称> <新名称>

  3. 重新提交:git push origin <新名称>:<新名称>

五、Git 图形化工具教程

SourceTree:

「SourceTree」官方下载:https://www.sourcetreeapp.com/

资料:

觉得文章对您有帮助请我喝杯咖啡吧^_^
0%