• 版本控制工具 Git


    1. 版本控制工具

    使用文件或文件夹进行版本管理,有缺点:
    
    多个文件,保留所有版本时,需要将多个文件保存在本地
    协同操作,多人协同操作时,需要将文件发来发去...
    容易丢失,被删除意味着永远失去(可以选择网盘)
    为了解决上述问题,应运而生了版本管理工具:
    
    VSS-- Visual Source Safe
    此工具是Microsoft提供的,是使用的相当普遍的工具之一,他可以与VS.net进行无缝集成,成为了独立开发人员和小型开发团队所适合的工具,基本上Window平台上开发的中小型企业,当规模较大后,其性能通常是无法忍受的,对分支与并行开发支持的比较有限。
    CVS--Concurrent Versions System
    此工具是一个开源工具,与后面提到的SVN是同一个厂家:Collab.Net提供的。CVS是源于unix的版本控制工具,对于CVS的安装和使用最好对unix的系统有所了解能更容易学习,CVS的服务器管理需要进行各种命令行操作。目前,CVS的客户端有winCVS的图形化界面,服务器端也有CVSNT的版本,易用性正在提高。
    SVN --CollabNet Subversion
    此工具是在CVS 的基础上,由CollabNet提供开发的,也是开源工具,应用比较广泛。他修正cvs的一些局限性,适用范围同cvs,目前有一些基于SVN的第三方工具,如TortoiseSVN,是其客户端程序,使用的也相当广泛。在权限管理,分支合并等方面做的很出色,他可以与Apache集成在一起进行用户认证。不过在权限管理方面目前还没有个很好用的界面化工具,SVNManger对于已经使用SVN进行配置的项目来说,基本上是无法应用的,但对于从头开始的项目是可以的,功能比较强大,但是搭建svnManger比较麻烦。是一个跨平台的软件,支持大多数常见的操作系统。作为一个开源的版本控制系统,Subversion 管理着随时间改变的数据。 这些数据放置在一个中央资料档案库中。 这个档案库很像一个普通的文件服务器, 不过它会记住每一次文件的变动。 这样你就可以把档案恢复到旧的版本, 或是浏览文件的变动历史。Subversion 是一个通用的系统, 可用来管理任何类型的文件, 其中包括了程序源码。
    BitKeeper
    是由BitMover公司提供的,BitKeeper自称是“分布式”可扩缩SCM系统。不是采用C/S结构,而是采用P2P结构来实现的,同样支持变更任务,所有变更集的操作都是原子的,与svn,cvs一致。
    GIT
    Git是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理.Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Torvalds 开始着手开发 Git 是为了作为一种过渡方案来替代 BitKeeper,后者之前一直是 Linux 内核开发人员在全球使用的主要源代码工具。开放源码社区中的有些人觉得 BitKeeper 的许可证并不适合开放源码社区的工作,因此 Torvalds 决定着手研究许可证更为灵活的版本控制系统。尽管最初 Git 的开发是为了辅助 Linux 内核开发的过程,但是我们已经发现在很多其他自由软件项目中也使用了 Git。例如 最近就迁移到 Git 上来了,很多 Freedesktop 的项目也迁移到了 Git 上。
    版本管理工具都一般包含客户端和服务端:
    
    客户端(用户):本地编写内容,向服务端获取或提交内容
    服务端(网盘):保存所有版本的文件
    View Code

    Git使用

     1 git init 初始化
     2 生成.git
     3 
     4 ---------工作区--------------- ---------------缓存区-----------版本库(.git)
     5                                  git.add                           git.commit
     6 原本的文件|被修改的文件
     7 git会自动检测哪些文件被修改了
     8 
     9 git status  查看状态
    10 
    11 git add 文件名
    12 git commit -m '提交信息'
    13 
    14 git ls-tree head   查看版本库中的文件
    15 git ls-files -s      查看版本和缓存区所有的文件
    16 
    17 commit之前要配置用户信息:
    18 git config --local user.name ''
    19 git config --local user.email ''
    第一阶段
     1          回滚:
     2                git reset --hard 版本号
     3                git log
     4 
     5          回滚到回滚之前的状态:
     6                 git reflog
     7 
     8                 git reset --max   a615783
     9 
    10        修改bug的方式:
    11        方式一:
    12                出现了一个bug:   出现bug的文件与正在做修改的文件不同
    13           git stash         将当前已经做过的修改,保存到一个临时的地方
    14           修复线上的bug
    15           git stash list    查看临时的地方保存的修改
    16           git stash pop  将临时的地方放置的修改内容重新放回到工作区
    17 
    18       又出现了一个bug:   出现bug的文件与正在做修改的文件相同
    19            git stash
    20            修复bug
    21            git stash pop 出现冲突,手动解决
    22                   列:
    23 <<<<<<< Updated upstream
    24 同城交友网站
    25 张小戈
    26 =======
    27 同城交友网站
    28 张小戈
    29 开发直播功能到一半
    30 >>>>>>> Stashed changes
    31 
    32        其他:
    33                  git stash apply
    34                  git stash drop
    35 
    36        方式二:
    37                    分支   master :只保留线上版本
    38                              dev:开发版本
    39                              bug:改bug版本
    40 
    41                    git branch dev    创建分支     注意当前所在分支,根据当前分支复制一份
    42                    git  checkout dev    进入分支
    43 
    44                     出现bug:
    45                           git checkout master
    46                           git branch bug
    47                           git checkout bug
    48                           修复bug
    49                     合并:
    50                            git checkout master
    51                            git merge bug
    52                      删除bug分支:
    53                            git branch -d bug
    54                      继续开发:
    55                             git checkout dev
    56                             ..........
    57                      合并:
    58                            git checkout master
    59                            git merge dev
    60                            无冲突:过
    61                            有冲突: 手动修改............
    第二阶段

     1 公司:
     2 git remote add origin https://github.com/a877252372/wwwww.git   建立远程连接别名
     3 
     4 git checkout master
     5 git push origin master # 推送 到远程仓库
     6 git push origin dev
     7 下班回家
     8 回家:
     9 git clone https://github.com/a877252372/wwwww.git    克隆到自己的电脑上
    10 
    11 cd wwwww
    12 
    13 git branch dev origin/dev  根据远程仓库的dev建立开发分支
    14 git checkout dev
    15 
    16 写代码
    17 
    18 git add .
    19 git commit ...
    20 git push origin dev    # 推送 到远程仓库
    21 
    22 公司:
    23 git checkout dev
    24 git fetch origin dev
    25 git pull origin dev 劲大   首先更新代码,避免冲突推送不成功
    26 
    27 功能11
    28 git add .
    29 git commit ...
    30 git push origin dev
    31 
    32 功能12:(忘记提交,下班回家)
    33 git add .
    34 git commit ...
    35 回家:
    36 git branch dev
    37 git pull origin dev
    38 功能13:
    39 git add .
    40 git commit ...
    41 git push origin dev
    42 公司:
    43 获取代码,
    44 git pull origin dev   首先更新代码,避免功能12与远程仓库中的功能13冲突推送不成功
    45 
    46 无冲突:过
    47 有冲突:
    48 手动解决
    49 git add .
    50 git commit -m '解决冲突'
    第三阶段:远程仓库

    什么是Git

    通过前面的学习了解到GitHub 是基于 Git 的,所以也就意味着 Git 是基础,如果不会使用 Git ,那么接下来会完全继续不下去,因此,今天的课程就来说说 Git ,本课程先介绍一些最基本的、最常用的一些 Git 知识,争取让你迅速掌握 Git 。

    1. 什么是 Git?

    Git 是 Linux 发明者 Linus 开发的一款新时代的版本控制系统,那么到底什么是版本控制系统呢?网上各种详细的介绍,大多枯燥乏味,对于新手很难理解,这里只举几个例子来帮助大家理解。

    熟悉编程的人都知道,在软件开发中源代码是最重要的,那么对源代码的管理也就变得更加重要了,以下几种情况在开发中最为常见:

    • 在开发程序时,为了防止代码丢失,需要在本地机器与远程服务器各存放一份,并且还需要有一套机制使本地可以与远程同步;
    • 开发中通常是几个人做同一个项目,要对同一份代码做更改,这个时候既需要大家互不影响,又需要各自可以同步别人的代码;
    • 开发的过程中免不了有bug,有时候刚发布的功能就出现了严重的bug,这个时候需要紧急对代码进行还原;
    • 随着版本迭代的增多,作为开发者需要清楚的知道每一个历史版本的代码更改记录,甚至知道每个人历史提交代码的情况。

    以上的这些情况,都是版本控制系统可以解决的问题。版本控制实际上就是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统,对于软件开发领域来说版本控制是最重要的环节,而 Git 毫无疑问是当下最流行、最好用的版本控制系统。

    2.Git 安装

    Git 是一个版本控制系统,也可以理解为一个工具,跟 Java 类似,使用之前必须先进行下载安装, Mac 笔记本上其实系统自带了 Git ,不过这里统一提供各平台的安装方式,这部分就不过多介绍,相信大家可以搞定。

    3.如何学习 Git

    安装好 Git 之后,怎么学习是个问题,其实关于 Git 有很多图形化的软件可以操作,这里推荐大家使用命令行开始学习,如果你没接触过命令行,开始可能会有所抵触,但是大量实践证明,只有一开始学习命令行,才能让你对 Git 的每一步操作有深刻的理解,而在熟练掌握之后,使用任何的图形化的软件都可以去操作。

    Git命令列表

    怎么判断 Git 有没有安装成功?在命令行里输入 git ,如果出现以下提示证明你已经安装成功了。我的运行环境是在window上,如果是在mac上,道理是一样的

    Git 所有的操作命令开头都要以 git 开头,上面列举了最常用的一些 Git 命令,后面有一句英文解释这个命令的意义,都是比较简单的词汇,不妨试着翻译一下,但是如果没有实际操作仍然不好理解,下面就以一个实际的操作来介绍一些常用命令的含义。

    Git常用命令举例

    第一步,需要新建一个文件夹,在文件夹里新建一个文件(我是用 Linux 命令新建的,Windows用户可以自己手动新建)

    • mkdir test (创建文件夹test)
    • cd test (切换到test目录)
    • touch a.md (新建a.md文件)

    注意:在进行任何 Git 操作之前,都要先切换到 Git 仓库目录,也就是要先切换到项目的文件夹目录下。

    可以是用cmd下cd到目录下,

    也可以是图形操作到项目目录下,右键git bash here

    最终回打开另外一个命令窗口:

    这个时候随便操作一个命令,比如 git status ,可以看到如下提示(不要纠结颜色,配置与主题不一样而已):

    意思是当前目录还不是一个 Git 仓库。

    1.git init

    这个时候就要用到第一个命令了,代表初始化 git 仓库,输入 git init 之后会提示:

    可以看到初始化成功了,至此 test 目录已经是一个 git 仓库了。

    2.git status

    接下来输入 git status 命令,会有如下提示:

    默认就直接在 master 分支,关于分支的概念后面会提,这时最主要的是提示 a.md 文件 Untracked files ,就是说 a.md 文件没有被跟踪,还没有提交到 git 仓库里,提示可以使用 git add 去操作想要提交的文件。

    git status 这个命令顾名思义就是查看状态,这是一个使用最频繁的命令,建议大家可以经常输入这个命令,来查看当前 git 仓库的一些状态。

    3.git add

    上面提示 a.md 文件还没有提交到 git 仓库里,这个时候我们可以随便编辑下 a.md 文件,然后输入 git add a.md ,然后再输入 git status :

    此时提示以下文件 Changes to be committed , 意思就是 a.md 文件等待被提交,当然你可以使用 git rm --cached 这个命令去移除这个缓存。

    4.git commit

    接着我们输入 git commit -m 'first commit' ,这个命令什么意思呢? commit 是提交的意思,-m 代表是提交信息,执行了以上命令代表我们已经正式进行了第一次提交。

    这个时候再输入 git status ,会提示 nothing to commit。

    5.git log

    此时输入 git log 命令,会显示如下内容:

    git log 命令可以查看所有产生的 commit 记录,从上图中可以看到已经产生了一条 commit 记录,而提交时候的附带信息叫 'first commit' 。

    git log可以做很多事,比如查看文件的修改信息

    git log -s --pretty=oneline filename 查看文件名为filename的提交记录

    $ git log -s --pretty=oneline yangzai.txt
    d60e15f257d8d053ae1ef3317ac10bfcc1224dda yangzai3
    ce5eb844870a8632bd5656550cb5130537acb245 yangzai2
    4ac92c649ef2b80c118541a51745e7de174b670c 冲突测试
    29d341e68865438bccdc6c4ac1b3296bffb356fc oldsyang-init
    

    如上所述,每一行最前面的那一长串数字就是每次提交形成的哈希值,然后就可以根据这个哈希值,配置git show命令就可以查看修改的具体信息

    $ git show 4ac92c649ef2b80c118541a51745e7de174b670c
    commit 4ac92c649ef2b80c118541a51745e7de174b670c
    Author: liuguniang <liuguniang1015@foxmail.com>
    Date:   Mon Aug 7 19:08:16 2016 +0800
    
        冲突测试
    
    diff --git a/yangzai.txt b/yangzai.txt
    index 190a180..8d38505 100644
    --- a/yangzai.txt
    +++ b/yangzai.txt
    @@ -1 +1 @@
    -123
    +456
    

    6.git add & git commit

    看到这里估计很多人会有疑问,我想要提交直接进行 commit 不就行了么,为什么先要再 add 一次呢?首先 git add 是先把改动添加到一个「暂存区」,你可以理解成是一个缓存区域,临时保存你的改动,而 git commit 才是最后真正的提交。这样做的好处就是防止误提交,当然也可以将这两步合并成一步,后面再介绍,建议新手先按部就班的一步步来。将两个步骤合并为:git commit -am 'init'

    7.git branch

    branch 即分支的意思,分支的概念很重要,尤其是团队协作的时候,假设两个人都在做同一个项目,这个时候分支就是保证两人协同合作的最大利器。举个例子,A, B俩人在做同一个项目,但是不同模块,这个时候A新建了一个分支叫a, B新建了一个分支叫b,这样A、B对代码做的所有改动都在各自的分支下,互不影响,最终,各自的模块都完成后,可以把分支再合并起来。

    执行 git init 初始化git仓库之后会默认生成一个主分支 master ,也是你所在的默认分支,也基本是实际开发正式环境下的分支,一般情况下 master 分支不会轻易直接在上面操作的,可以输入 git branch 查看下当前分支情况:

    如果想在此基础上新建一个分支,只要执行 git branch a 就新建了一个名字叫 a 的分支,这时候分支 a 跟分支 master 是一模一样的内容,再输入 git branch 查看的当前分支情况:

    从上图可以看到 master 分支前有个 * 号,即虽然新建了一个 a 的分支,但是当前所在的分支还是在 master 上,如果想在 a 分支上进行开发,首先要切换到 a 分支上,执行 git checkout a 命令,然后再输入 git branch 查看下分支情况:

    可以看到当前所在分支已经是a了,这个时候 A 技术人员就可以尽情的在新建的a分支去进行代码改动了。

    可能有些技术人员会觉得先新建再切换会有些麻烦,下面就提供给大家一个简便的命令:

    git checkout -b a

    这个命令的意思就是新建一个a分支,并且自动切换到a分支。

    8.git merge

    A技术人员在a分支下代码写的不亦乐乎,终于他的模块完成了,并且测试也都通过了,准备要上线,这个时候就需要把他的代码合并到主分支master上,然后发布。git merge 就是合并分支用到的命令,针对上述情况,需要完成两个步骤,第一步是切换到 master 分支,如果已经在了就不用切换了,第二步执行 git merge a ,意思是把a分支的代码合并到master分支,不出意外,这个时候a分支的代码就顺利合并到 master 分支上了。为什么说不出意外呢?因为这个时候可能会有冲突而造成合并失败,留个包袱,后面进阶的时候再讲。

    9.git branch -d

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

    10.git branch -D

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

    11.git tag

    客户端开发的时候经常有版本的概念,比如v1.0、v1.1等,不同的版本对应不同的代码,所以一般要给代码加上标签,这样假设v1.1版本出了一个新bug,但是又不清楚v1.0是不是有这个bug,有了标签就可以顺利切换到v1.0的代码,重新打包测试。

    新建一个标签很简单,比如 git tag v1.0 就代表在当前代码状态下新建了一个v1.0的标签,输入 git tag 可以查看历史 tag 记录。

    从上图可以看出新建了两个标签 v1.0、v1.1。

    想要切换到某个tag怎么办?也很简单,执行 git checkout v1.0 命令,就顺利切换到 v1.0 tag的代码状态了。

    12 git rm

    如果对已经提交的数据文件,想要彻底排除,并且以后都不再提交,操作如下:

    1. 使用git rm 文件路劲(这样的话会同时删除本地磁盘上的文件,如果不想删除物理文件请执行,git rm --cache 文件路径)
    2. git add .
    3. git commit -m '描述'
    4. 将文件名或者文件夹添加到 .gitignore文件里边去

    以上是一些最基本的Git操作,并且是在本地环境进行操作的,完全没有涉及到远程仓库,接下来的课程将以远程 GitHub 仓库为例,讲解本地如何与远程仓库一起同步协作,另外,本节课讲述的是最基础最简单的Git操作,后续会讲解一些Git的高阶以及一些Git的酷炫操作。

    向Github提交代码

    什么是SSH?

    通过课程「Git速成」的讲解,相信大家已经熟悉了本地 Git 仓库的基本操作,本节课来介绍下如何与远程仓库一起协作,向 GitHub 上提交你的第一行代码!

    拥有了一个 GitHub 账号之后,就可以自由的 clone 或者下载其他项目,也可以创建自己的项目,但是无法提交代码。仔细想想也知道,如果可以随意提交代码,那么 GitHub 上的项目岂不乱套了,所以提交代码之前一定是需要某种授权的,而 GitHub 上一般都是基于 SSH 授权的。

    那么什么是 SSH 呢?

    简单点说,SSH是一种网络协议,用于计算机之间的加密登录。目前是每一台 Linux 电脑的标准配置。而大多数 Git 服务器都会选择使用 SSH 公钥来进行授权,所以想要在 GitHub 提交代码的第一步就是要先添加 SSH key 配置。

    生成SSH Key

    Linux 与 Mac 都是默认安装了 SSH ,而 Windows 系统安装了 Git Bash 应该也是带了 SSH 的。大家可以在终端(win下在 Git Bash 里)输入 ssh 如果出现以下提示证明你本机已经安装 SSH, 否则请搜索自行安装下。

    接下来输入 ssh-keygen -t rsa 命名,意思是指定 rsa 算法生成密钥,接着连续三个回车键(不需要输入密码)就会生成两个文件 idrsa 和 idrsa.pub ,idrsa 是密钥,idrsa.pub 是公钥。这两个文件默认分别在如下目录里生成:

    Linux/Mac 系统 在 ~/.ssh 下,win系统在 /c/Documents and Settings/username/.ssh 下,都是隐藏文件,相信你们有办法查看的。

    接下来要做的是把 idrsa.pub 的内容添加到 GitHub 上,这样本地的 idrsa 密钥跟 GitHub 上的 id_rsa.pub 公钥进行配对,授权成功才可以提交代码。

    GitHub上添加SSH Key

    首先在 GitHub 上的设置页面,点击最左侧 SSH and GPG keys :

    然后点击右上角的 New SSH key 按钮:

    需要做的只是在 Key 那栏把 id_rsa.pub 公钥文件里的内容复制粘贴进去就可以了(上述示例为了安全粘贴的公钥是无效的),Title 栏不需要填写,点击 Add SSH key 按钮就ok了。

    这里提醒下,怎么查看 id_rsa.pub 文件的内容?

    Linux/Mac 用户执行以下命令:

    cd ~/.ssh cat id_rsa.pub Windows用户,设置显示隐藏文件,可以使用 EditPlus , Sublime或者vscode(本人非常推荐vscode,功能非常强大,微软出品) 打开复制就行了。

    SSH key 添加成功之后,输入 ssh -T git@github.com 进行测试,如果出现以下提示证明添加成功了

    Push & Pull 命令介绍

    在提交代码之前首先了解两个命令,这两个命令需要与远程仓库配合。

    Push :直译过来就是「推」的意思,如果你本地代码有更新,那么就需要把本地代码推到远程仓库,这样本地仓库跟远程仓库就可以保持同步了。

    代码示例: git push origin master

    意思就是把本地代码推到远程 master 分支。

    Pull:直译过来就是「拉」的意思,如果别人提交代码到远程仓库,这个时候你需要把远程仓库的最新代码拉下来,然后保证两端代码的同步。

    代码示例: git pull origin master

    意思就是把远程最新的代码更新到本地。一般在 push 之前都会先 pull ,这样不容易冲突(最好强制要求自己这样)。

    提交代码

    添加 SSH key 成功后,就有权限向 GitHub 提交自己的项目代码了,提交代码有两种方法:

    (1)Clone自己的项目

    此处以我在 GitHub 上创建的 test 项目为例,执行如下命令:

    git clone git@github.com:oldsyang/newtest.git

    这样就把 newtest 项目 clone 到了本地,可以把 clone 命令理解为高级的复制,这个时候该项目本身就已经是一个git 仓库了,不需要执行 git init 进行初始化,并且已经关联好了远程仓库,只需要在这个 test 目录下任意修改或者添加文件,然后进行 commit ,之后就可以执行:

    git push origin master

    进行代码提交,这种是最简单方便的一种方式。

    怎么获取项目的仓库地址呢?如下图:

    (2)关联本地已有项目

    如果本地已经有一个完整的 git 仓库,并且已经进行了多次 commit ,这个时候第一种方法就不适合了。

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

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

    第二步把本地 test2 项目与 GitHub 上的 test 项目进行关联,切换到 test2 目录,执行如下命令:

    git remote add origin git@github.com:oldsyang/newtest.git

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

    查看当前项目有哪些远程仓库可以执行如下命令:

    git remote -v

    接下来,本地的仓库就可以向远程仓库进行代码提交了:

    git push origin master

    此命令就是默认向 GitHub 上的 newtest 目录提交了代码,这个代码是在 master 分支。当然你可以提交到指定的分支,这个之后的文章再详细讲解。

    注意:在提交代码之前先要设置下自己的用户名与邮箱,这些信息会出现在所有的 commit 记录里,执行以下代码就可以设置:

    git config —global user.name "newtest"

    git config —global user.email "545329979@qq.com"

    总结

    通过本课时的介绍,终于可以成功的向 GitHub 提交代码了,但是相信大家还有很多疑问,比如关于分支的理解与使用,比如 Git 的其他一些有用的配置,比如怎么向一些开源项目贡献代码,发起 Pull Request 等,之后的系列文章会逐一进行介绍。

    Git进阶

    用户名和邮箱

    通过前面的学习,相信大家已经可以使用 Git 管理自己的代码了,但这些还远远不够,关于Git还有很多知识与技巧,接下来就给大家介绍一些 Git 进阶的知识。

    在 GitHub 上的每一次commit都会产生一条log,这条log标记了提交人的姓名与邮箱,目的是便于其他人查看与联系提交人,因此,进行提交代码的第一步就是要设置自己的用户名与邮箱。执行以下命令:

    git config --global user.name "oldsyang"

    git config —global user.email "545329979@qq.com"

    以上进行了全局配置,如果某一个项目想要使用特定的邮箱,那么只需切换到相应的项目,将上述代码中的 --global 参数去除,再重新执行一遍就可以了。

    注意:在 GitHub 上的每次提交理论上都会在主页的下方产生一条绿色小方块的记录,如果确认提交后,没有绿色方块显示,那一定是所提交代码配置的邮箱与当前 GitHub 上的邮箱不一致,GitHub 上的邮箱可以到 Setting -> Emails里查看。

    alias

    一些Git命令操作很频繁,例如:

    git commit
    git checkout
    git branch
    git status
    

    对于这些频繁的操作,每次都要输入完全确实有些麻烦,有没有一种简单的缩写输入呢?比如对应的直接输入以下:

    git c
    git co
    git br
    git s
    

    是不是很简单快捷?这个时候就用到alias配置,翻译过来就是别名的意思,输入以下命令就可以直接满足以上的需求。

    git config --global alias.co checkout  # 别名
    git config --global alias.ci commit
    git config --global alias.st status
    git config --global alias.br branch
    

    当然以上别名不是固定的,可以根据自己的习惯去定制,除此之外还可以设置组合,比如:

    git config --global alias.psm 'push origin master'
    git config --global alias.plm 'pull origin master'
    

    之后经常用到的git push origin master 和 git pull origin master ,直接使用 git psm 和 git plm 就可以代替。

    这里给大家推荐一个很强大的 alias 命令,当输入 git log 查看日志

    如果输入

    git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative 
    

    日志就会变的更有趣

    其他配置

    当然还有一些其他有用的配置,默认情况下 git 用的编辑器是 vi ,如果不喜欢可以改成其他编辑器,比如 vim 。

    git config --global core.editor "vim" # 设置Editor使用vim

    如果喜欢其他编辑器可自行搜索配置,前提是本机有安装。

    有些人会疑问怎样才能让终端显示各种颜色,输入如下命令即可:

    git config --global color.ui true

    还有些其他的配置如:

    git config --global core.quotepath false # 设置显示中文文件名

    以上基本的配置就差不多了,默认这些配置都在 ~/.gitconfig 文件下的,你可以找到这个文件查看自己的配置,也可以输入 git config -l 命令查看。

    git ls-tree head #查看当前版本库里的文件树

    git ls-files #查看缓存区和版本库里的所有文件

    diff

    diff命令是很常用的,在开发过程中,大家会经常做一些代码改动,但时间久了难免会忘记做过哪些改动,在提交之前需要确认下,这个时候就可以用diff来查看到底做了哪些改动,例如,有一个 a.md 的文件,做了一些改动,当输入 git diff 时,就会看到如下内容:

    红色的部分前面有个 - 代表删除的内容,绿色的部分前面有个 + 代表增加的内容,从这里可以一目了然的知道自己到底对这个文件做了哪些改动。

    需要注意的是,直接输入 git diff 只能比较当前文件和暂存区文件差异,什么是暂存区?就是还没有执行 git add 的文件。

    当然除了与暂存区做比较之外,他还可以有其他用法,如比较两次 commit 之间的差异,比较两个分支之间的差异,比较暂存区和版本库之间的差异等,具体用法如下:

    • git diff <$id1> <$id2> # 比较两次提交之间的差异
    • git diff .. # 在两个分支之间比较
    • git diff --staged # 比较暂存区和版本库差异

    checkout

    checkout 一般用作切换分支使用,比如切换到 develop 分支,可以执行:

    git checkout develop

    但是 checkout 不只用作切换分支,也可以用来切换tag,切换到某次commit,如:git checkout v1.0

    git checkout ffd9f2dd68f1eb21d36cee50dbdd504e95d9c8f7 # 后面的长串是commit_id,是每次commit的SHA1值,可以根据 git log 看到。

    除了有“切换”的作用,checkout 还可以用作撤销,例如,假设在一个分支开发一个功能,写到一半时需求变化了,而且是大变化,之前写的代码完全不能用,目前还没有 git add 进暂存区,这个时候很简单的一个操作就可以直接把原文件还原:

    git checkout a.md

    注意,checkout 命令只能撤销还没有 add 进暂存区的文件。

    stash

    设想一个场景,假设我们正在一个新的分支做新的功能,这个时候突然有一个紧急的bug需要修复,而且修复完之后需要立即发布。技术人员可能会想先把刚写的一点代码进行提交就行了,这样做理论上是没问题的,但是原则上每次的 commit 都要有实际的意义,目前代码只是写了一半,是不建议 commit 的,那么有没有一种比较好的办法,可以暂时切到其他分支,修复完bug再切换回来,并且代码也能保留的?

    首先,暂存 commit 代码:

    此时, stash 命令就大有用处了,前提是当前代码没有进行 commit ,执行了 add 也没关系,首先执行命令:git stash

    意思就是把当前分支所有没有 commit 的代码先暂存起来,这个时候再执行 git status 命令,会发现当前分支很干净,几乎看不到任何改动,自己代码的改动也看不见,但其实是暂存起来了。

    执行命令 git stash list 会发现此时暂存区已经有了一条记录。

    其次:切换分支,代码还原:

    这个时候就可以切换到其他分支,把bug修复好,然后发布。一切都解决了,再切换回来继续之前没做完的功能,但之前的代码怎样还原呢?

    执行命令 git stash apply 会发现之前的代码全部回来了,就好像一切都没发生过一样。

    最后,删除暂存区记录:

    接下来最好把暂存区的stash 记录删除,执行:git stash drop 就把最近一条的 stash 记录删除了。

    代码还原其实还有更简便的,可以执行:git stash pop 来代替 apply 命令,pop 与 apply 的唯一区别就是 pop 不但会帮将代码还原,还会自动帮将本条 stash 记录删除,不需要手动 drop 了,为了验证你可以执行 git stash list 命令来确认是不是已经没有记录了。

    最后还有一个命令介绍下:

    git stash clear

    就是清空所有暂存区的记录,drop 是只删除一条,当然后面可以跟 stash_id 参数来删除指定的某条记录,没有参数就是删除最近的,而 clear 是清空。

    reset

    git reset HEAD filename 撤销文件名filename的所有修改(还没有commit的,只是add进暂存区的)

    大家肯定在开发的时候,都遇到过想全部回滚到某一个节点,丢弃掉现有的修改,这就reset大有用处,先看一张图(上图)

    比如,现在我已经有三次提交记录了:

    先查看git log:
    ```bash
    $ git log
    commit 9f0dc164fad0776ce7ad80a2a064a9840877bf75
    Author: oldsyang <545329979@qq.com>
    Date:   Mon Aug 7 10:34:18 2016 +0800
    
        three
    
    commit 108cee428009a066fde2f88c79f797da07e51080
    Author: oldsyang <545329979@qq.com>
    Date:   Mon Aug 7 10:33:46 2016 +0800
    
        second
    
    commit f41d81394a6b524aa35215da926da30d42b64add
    Author: oldsyang <545329979@qq.com>
    Date:   Mon Aug 7 10:33:25 2016 +0800
    
        init
    

    现在的需求是回滚到第二次提交的状态(second),找到第二次提交的哈希值

    git reset --hard  108cee428009a066fde2f88c79f797da07e51080
    

    在执行git log或者git ls-files,就发现回滚到第二次的提交的最原始状态(相当于是第一次提交完成后的状态)

    那如果现在还想回到three状态?

    先执行 git reflog

    $ git reflog
    3242www HEAD@{1}: reset: moving to 9f0dc164fad0776ce7ad80a2a064a9840877                      bf75
    9f0dc16 HEAD@{2}: commit: three
    108cee4 HEAD@{3}: commit: second
    f41d813 HEAD@{4}: commit (initial): init
    

    再执行 git reset --hard 9f0dc16

    $ git reset 9f0dc16
    Unstaged changes after reset:
    

    这样就整个又回到之前的状态

    merge & rebase

    大家都知道 merge 分支是合并的意思,当在一个 featureA 分支开发完一个功能需要合并到主分支 master 上时,只需要进行如下操作:

    git checkout master
    git merge featureA
    

    其实 rebase 命令也是合并的意思,上面的需求同样可以进行如下操作:

    git checkout master git rebase featureA rebase 跟 merge 的区别?

    可以理解成有两个书架,你需要把两个书架的书整理到一起,第一种做法是 merge ,简单粗暴,直接空出一块地方把另一个书架的书全部放进去,这种做法你可以知道哪些书是来自另一个书架;第二种做法就是 rebase ,会对两个书架的书先进行比较,按照购书的时间重新排序,然后重新放置好,这样做的好处就是合并之后的书架看起来逻辑清晰,但是很难清楚的知道哪些书来自哪个书架。

    只能说各有好处的,不同的团队根据不同的需要以及不同的习惯来选择就好。

    解决冲突

    假设这样一个场景,A和B两位技术人员各自建了两个分支来开发不同的功能,大部分情况下都会尽量互不干扰的,但是有一个需求A需要改动一个基础库中的一个类的方法,不巧B这个时候由于业务需要也改动了基础库的这个方法,因为这种情况比较特殊,A和B都认为不会对地方造成影响,等两人各自把功能做完了,需要合并的到主分支 master 的时候,假设先合并A的分支,这个时候没问题,之后再继续合并B的分支,这个时候就会有冲突了,因为A和B两个人同时更改了同一个地方,Git 本身不能判断谁更改的对,但是这个时候他会智能的提示有 conflicts ,需要手动解决这个冲突之后再重新进行一次 commit 提交。接下来,随便在项目中制造一个冲突做演示:

    上图就是冲突的示例,冲突的地方由 ==== 分出了上下两个部分,上半部分 HEAD 是当前所在分支的代码,下半部分是 baiduactivity 分支的代码,从图中可以看出 HEAD 对 gradle 插件进行了升级,同时新增了一个插件,所以很容易判断哪些代码该保留,哪些代码该删除,我们只需要移除掉那些老旧代码,同时也要把那些 <<< HEAD、==== 以及 >>>>>>baiduactivity 标记符号删除,最后进行一次 commit 就可以了。

    在开发的过程中,一般都会约定大家写的代码尽量不要彼此影响,以减少出现冲突的可能,但是冲突总归无法避免,技术人员们需要了解并掌握解决冲突的方法。

    Git分支常用操作

    Git 相对于 SVN 最强大的优势就在于「分支」,Git 的分支操作简单方便,而实际项目开发中团队合作最依赖的莫过于分支了,关于分支前面的课时也提到过,本课时会详细讲述什么是分支、分支的具体操作以及实际项目开发中是怎样依赖分支进行团队合作的。

    1. 什么是分支?

    对于分支这个概念,可以这样理解,几个人一起去旅行,走到一个三岔口,每条路可能有不同的风景,大家约定 3 天之后在某地汇聚,然后各自出发了。这三条分叉路就可以理解为各自的分支,而大家汇聚的时候就相当于将各自的分支进行了合并。

    1. 分支的常用操作

    通常默认会有一个主分支叫 master ,下面首先来介绍一下关于分支的一些基本操作:

    (1)新建一个叫 develop 的分支

    git branch develop

    注意,新建分支的命令是基于当前所在分支进行的,即以上是基于 mater 分支新建了一个叫做 develop 的分支,此时 develop 分支与 master 分支的内容完全一样。例如,有 A、B、C三个分支,各分支内容不同,如果当前是在 B 分支,执行新建分支命令,则新建的分支内容与 B 分支相同,同理如果当前在 C 分支,那就是基于 C 分支基础上新建的分支。

    (2)切换到 develop 分支

    git checkout develop

    如果把以上两步合并,即新建并自动切换到 develop 分支:

    git checkout -b develop

    (3)把 develop 分支推送到远程仓库

    git push origin develop

    如果你远程的分支想取名叫 develop2 ,执行以下代码:

    git push origin develop:develop2

    注意:实际开发管理,建议不要这样做,这样会导致很混乱,难管理,建议本地分支与远程分支名称要保持一致。

    在某些情况下,你需要对别人的提交(也可能是你自己的),进行强制覆盖

    git push --force

    (4)查看本地分支列表

    git branch

    (5)查看远程分支列表

    git branch -r

    git branch -a

    (6)删除本地分支

    git branch -d develop

    git branch -D develop (强制删除)

    (7)删除远程分支

    git push origin :develop

    如果远程分支有 develop ,而本地没有,想要将远程的 develop 分支迁到本地:

    git checkout develop origin/develop

    同样的把远程分支迁到本地,并顺便切换到该分支:

    git checkout -b develop origin/develop

    基本的团队协作流程

    一般来说,如果是一个人开发,可能只需要 master、develop 两个分支就可以了,平时开发在 develop 分支进行,开发完成之后,发布之前合并到 master 分支,这个流程不会有大问题。

    如果是 3、5 个人,那就不一样了,有人觉得也不会有什么大问题,直接新建 A、B、C 三个人的分支,每人各自开发各自的分支,然后开发完成之后再逐步合并到 master 分支,然而现实情况是,当某人正在某个分支开发某个功能时,突然发现线上有一个很严重的 bug ,不得不停下手头的工作优先处理 bug ,并且很多时候多人协作下如果没有一个规范,很容易产生问题,所以多人协作下的分支管理规范很重要,就像代码规范一样重要,接下来就向大家推荐一种分支管理流程 Git Flow。

    GitFlow详细操作

    准确的说 Git Flow 是一种比较成熟的分支管理流程,我们先看一张图能清晰的描述他整个的工作流程:

    第一次看上面的图是不是有些晕,接下来用简单的语言给大家解释一下。

    一般开发来说,大部分情况下都会拥有两个分支 master 和 develop,他们的职责分别是:

    • master:永远处在即将发布(production-ready)状态
    • develop:最新的开发状态

    确切的说 master、develop 分支大部分情况下都会保持一致,只有在上线前的测试阶段 develop 比 master 的代码要多,一旦测试没问题,准备发布时,会将 develop 合并到 master 上。

    但是产品发布之后又会进行下一版本的功能开发,开发中间可能又会遇到需要紧急修复的 bug ,一个功能开发完成之后突然需求变动了等情况,所以 Git Flow 除了以上 master 和 develop 两个主要分支以外,还提出了以下三个辅助分支:

    • feature: 开发新功能的分支, 基于 develop, 完成后 merge 回 develop
    • release: 准备要发布版本的分支, 用来修复 bug,基于 develop,完成后 merge 回 develop 和 master
    • hotfix: 修复 master 上的问题, 等不及 release 版本就必须马上上线. 基于 master, 完成后 merge 回 master 和 develop

    举个例子,假设已经有 master 和 develop 两个分支了,这个时候准备做一个功能 A,第一步要做的就是基于 develop 分支新建个分支:

    git branch feature/A

    其实就是一个规范,规定了所有开发的功能分支都以 feature 为前缀。

    但是这个时候发现线上有一个紧急的 bug 需要修复,可以立刻切换到 master 分支,然后再此基础上新建一个分支:

    git branch hotfix/B

    代表新建一个紧急修复分支,修复完成之后直接合并到 develop 和 master ,然后发布。

    然后再切换回 feature/A 分支继续开发,如果开发完了,那么合并回 develop 分支,然后在 develop 分支属于测试环境,跟后端对接并且测试,感觉可以发布到正式环境了,这个时候再新建一个 release 分支:

    git branch release/1.0

    此时,所有的 api、数据等都是正式环境,然后在这个分支上进行最后的测试,发现 bug 直接进行修改,直到测试,达到发布的标准,就可以把该分支合并到 develop 和 master 然后进行发布。

    以上就是 Git Flow 的概念与大体流程,看起来有些复杂,但是对于人数比较多的团队协作现实开发中确实会遇到这种复杂的情况, Git Flow 是目前很流行的一套分支管理流程,但是有人会觉得每次都要进行各种合并操作有些麻烦, Git Flow 为此专门推出了一个工具,并且是开源的:GitHub 开源地址:[https://github.com/nvie/gitflow]

    简单来说,这个工具会帮大家节省很多步骤,例如,当前处于 master 分支,如果想要开发一个新的功能,第一步切换到 develop 分支,第二步新建一个以 feature 开头的分支名,有了 Git Flow 直接如下操作就可以完成了:

    git flow feature start A

    这个分支完成之后,需要合并到 develop 分支,进行如下操作:

    git flow feature finish A

    如果是 hotfix 或者 release 分支,会自动合并到 develop、master 两个分支。

    到目前为止,大家已经了解了这个工具的具体作用,具体安装与用法就不多介绍了,感兴趣的技术人员可以观看这篇博客:

    http://stormzhang.com/git/2014/01/29/git-flow/

    总结

    以上就是分享给大家的关于分支的所有知识,一个人你也许感受不到什么,但是实际工作中大都以团队协作为主,而分支是团队协作必备技能,Git Flow 是一个很流行的分支管理流程,也是公司团队内部经常使用的一套流程,希望大家能够掌握。

    分支视频讲解

    后续补上

    Github常见的几种操作

    有哪些常见的操作?

    开源社区最大的魅力是人人都可以参与进去,发挥众人的力量,让一个项目更完善,更强壮。那么就会有人疑问,自己目前还没有能力开源一个项目,但是又想一起参与到别人的开源项目中,该怎样操作呢?本课时,就来给大家介绍 GitHub 上的一些常见的操作。

    下面以 Square 公司开源的 Retrofit 为例来介绍。

    打开链接:https://github.com/square/retrofit ,可以看到如下的项目主页:

    从上图可以看出,一个项目可以进行的操作主要有两部分,第一部分包括 Watch、Star、Fork ,这三个操作前面的课时已经介绍过了,这里不做重复讲解。

    着重介绍第二部分,分别包括 Code、Issues、Pull requests、Projects、Wiki、Pulse、Graphs。接下来一一进行讲解。

    (1)Code

    代表项目的代码文件,每个项目通常都会有对该项目的介绍,只需要在项目的根目录里添加一个 README.md 文件就可以,使用 markdown 语法,GitHub 自动会对该文件进行渲染。

    (2)Issues

    Issues 代表该项目的一些问题或者 bug,并不是说 Issue 越少越好,Issue 被解决的越多说明项目作者或者组织响应很积极,也说明该开源项目的作者很重视。观察 Retrofit 的 Issues 主页,截至目前 close(解决) 了 1305 个 Issue,open (待解决)状态的有 37 个,这种解决问题的比例与速度值得每位开源项目的作者学习。

    同样的,大家在使用一些开源项目遇到问题的时候都可以提 Issue,可以通过点击右上角的 New Issue 来新建 Issue,添加一个标题与描述就可以了,这个操作很简单。

    (3)Pull requests

    别人开源一个项目,如果我们想一起参与开发,一起来完善,这就要通过 Pull requests 来完成,简称 PR。

    (4)Projects

    这个是最新 GitHub 改版新增的一个项目,这个项目就是方便将一些 Issues、Pull requests 进行分类,目前为止该功能被使用的比较少,了解一下就好。

    (5)Wiki

    一般来说,项目的主页有 README.md 基本就够了,但是有些时候项目的一些用法很复杂,需要有详细的使用说明文档给使用者,这个时候就用到了 Wiki。

    Wiki使用起来也很简单,直接 New Page ,然后使用 markdown 语法即可进行编写。

    (6)Pulse

    Pulse 可以理解成该项目的活跃汇总。包括近期该仓库创建了多少个 Pull Request 或 Issue,有多少人参与了这个项目的开发等,在这里都可以一目了然。

    根据这个页面,用户可以判断该项目受关注程度以及项目作者是否还在积极参与解决这些问题等。

    (7)Graphs

    Graphs 是以图表的形式来展示该项目的一个整体情况。比如项目的全部贡献人,commits 的围度分析,某天代码提交的频繁程度等。

    (8)Settings

    如果一个项目是自己的,那么你会发现有一个菜单 Settings,这里包括了对整个项目的设置信息与功能,比如对项目重命名,删除该项目,关闭项目的 Wiki 和 Issues 功能等,不过大部分情况下都不需要对这些设置做更改。感兴趣的技术人员,可以自行了解这里的设置有哪些功能。

    以上就包含了一个 GitHub 项目的所有操作,对初学者来说难度最主要的还是发起 Pull request,不过相信大家看完之后对 GitHub 上一些常用的操作应该已经熟悉了,从现在开始,请一起参与到开源社区中来吧,开源社区需要每个人都贡献一份力量,这样才能够越来越强大,也能够对更多的人有帮助!

    实践:提交自己的第一个PR

    接下来我们向项目 newtest 发起 PR操作,说明,必须确保你可以正常向 GitHub 提交代码,如果不可以的话,请仔细观看前面课时讲解的内容。

    第一步,登录你的 GitHub 账号,然后找到想要发起 PR 的项目,这里以 newtest 为例,地址:

    https://github.com/oldsyang/newtest

    点击右上角的 Fork 按钮,该项目就出现在你自己账号的 Repository 里。

    注意,这个项目原本是属于 GitHub 账号 oldsyang 下的,为了演示,我自己又重新注册了另一个账号叫 yangzaizai 。

    Fork 之后,在账号 yangzaizai 下多了一个 newtest 的项目,如下图:

    从上图可以看出 Fork 过来的项目标题底部会显示一行小字:forked from oldsyang/newtest ,除此之外,项目代码跟原项目一模一样,对于原项目来说,相当于别人新建了一个分支而已。

    第二步,把该项目 clone 到本地,把自己新增或者改动的代码保存。

    第三步,把自己做的代码改动 push 到你自己 GitHub 的项目上去。

    第四步,点击你 Fork 过来的项目主页的 Pull requests 页面。

    点击 New pull request 按钮会看到如下页面:

    这个页面会自动比较该项目与原有项目的不同之处,最顶部声明了是 oldsyang/newtest 项目的 master 分支与你 fork 过来的 yangzaizai/newtest 项目的 master 分支所做的比较。

    最底部可以方便直观的看到代码中做了哪些改动,这里可以看到我加了一句 Fork from oldsyang !

    同样的,写好标题和描述,然后点击中间的 Create pull request 按钮,至此就成功给该项目提交了一个 PR。

    然后就等着项目原作者 review 你的代码,并且决定会不会接受你的 PR,如果接受,那么你就已经是该项目的贡献者之一了。

    建立组织

    在github可以创建一个组织去协同开发好多项目,操作比较简单

    点击个人头像下拉菜单里的setting选项,

    在左侧点击organizations选项,

    在右上角点击 New Organization,然后安装提示注册一个组织

    创建完成之后就出现详情页面

    在这个页面就可以创建仓库和邀请成员了,邀请成员后,github会邮件的形式通知被邀请的成员

    发现好用的开源项目

    关注一些活跃的大牛

    经过前面的学习,有技术人员可能会觉得,GitHub 大概了解了,Git 也差不多会使用了,但还是搞不清 GitHub 如何帮助大家提升工作效率,其实 GitHub 最重要的一个作用就是发现全世界最优秀的开源项目,你没事的时候刷刷微博、知乎,别人没事的时候刷刷 GitHub ,看看最近有哪些流行的项目,久而久之,差距就会越来越大,那么如何发现优秀的开源项目呢?本课时就来给大家介绍一下。

    GitHub 主页有一个类似微博的时间线功能,所有你关注的人的动作,比如 star、fork 了某个项目都会出现在你的时间线上,这种方式适合我这种比较懒的人,不用主动去找项目,这也是我每天获取信息的一个很重要的方式。不知道怎么关注这些人?那么很简单,关注我 oldsyang ,以及我 GitHub 上关注的一些大牛,基本就差不多了。

    点击下图的 Explore 菜单到“发现”页面

    点击下图的 Trending 按钮

    Trending 直译过来是趋势的意思,也就是说从这个页面可以看到最近一些热门的开源项目,这个页面是很多人主动获取一些开源项目最好的途径,可以选择「当天热门」、「一周之内热门」和「一月之内热门」来查看,并且还可以分语言类来查看,比如你想查看最近热门的 Android 项目,那么右边就可以选择 Java 语言。 这个页面推荐大家每隔几天就去查看一下,主动发掘一些优秀的开源项目。

    除了 Trending ,还有一种最主动的获取开源项目的方式,那就是 GitHub 的 Search 功能。

    例如,你是做 Android 的,接触 GitHub 没多久,那么第一件事就应该输入 android 关键字进行搜索,然后右上角选择按照 star 来排序,结果如下图:

    除此之外,GitHub 的 Search 还有一些小技巧,比如你想搜索的结果中 star 数大于1000的,那么可以这样搜索:

    android http stars:>1000

    当然还有些其他小技巧,这里就不多介绍了。

    如果使用 Google 浏览器,想要搜索 GitHub 上的结果,可以在前面加 GitHub 关键字,比如 输入 github python request ,每个关键字用空格隔开,基本也是想要的结果,只是不是单纯的按照 star 数来排序的。

    GitHub 上优秀开源项目真的是很多,就不一一推荐了,授人以鱼不如授人以渔,请大家自行发掘自己需要的开源项目吧,不管是应用在实际项目上,还是对源码的学习,都是提升自己工作效率与技能的很重要的一个渠道,总有一天,你会突然意识到,原来不知不觉你已经走了这么远。

  • 相关阅读:
    <<一线架构师实践指南>>读书笔记之二PA阶段
    【读书笔记】简约至上交互设计四策略第4章 删除
    大数据量简单数据查询设计思考
    识别项目干系人
    【读书笔记】简约至上交互设计四策略第3章 简约四策略
    【读书笔记】简约至上交互设计四策略第2章 明确认识
    【读书笔记】简约至上交互设计四策略第1章 话说简单
    采购管理计划
    项目管理整体的一些基本概念1
    【读书笔记】简约至上交互设计四策略第5章 组织
  • 原文地址:https://www.cnblogs.com/liuguniang/p/7301682.html
Copyright © 2020-2023  润新知