github使用入门

1. 在Mac OS X上安装Git

终端运行:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"


出现错误:

Press RETURN to continue or any other key to abort

==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/. /usr/local/etc /usr/local/share/man/man3 /usr/local/share/man/man5 /usr/local/share/man/man7 /usr/local/share/info /usr/local/share/doc

Password:

==> /usr/bin/sudo /usr/sbin/chown andy /usr/local/. /usr/local/etc /usr/local/share/man/man3 /usr/local/share/man/man5 /usr/local/share/man/man7 /usr/local/share/info /usr/local/share/doc

==> /usr/bin/sudo /bin/mkdir /Library/Caches/Homebrew

==> /usr/bin/sudo /bin/chmod g+rwx /Library/Caches/Homebrew

==> /usr/bin/sudo /usr/sbin/chown andy /Library/Caches/Homebrew

==> Downloading and installing Homebrew...

remote: Counting objects: 3770, done.

remote: Compressing objects: 100% (3609/3609), done.

remote: Total 3770 (delta 43), reused 539 (delta 26), pack-reused 0

Receiving objects: 100% (3770/3770), 3.21 MiB | 568.00 KiB/s, done.

Resolving deltas: 100% (43/43), done.

From https://github.com/Homebrew/homebrew

 * [new branch]      master     -> origin/master

error: unable to unlink old 'Library/Aliases/0mq' (Permission denied)

error: unable to unlink old 'Library/Aliases/4store' (Permission denied)

error: unable to unlink old 'Library/Aliases/Secret Rabbit Code' (Permission denied)

error: unable to create symlink Library/Aliases/actor-framework (Permission denied)

error: unable to create symlink Library/Aliases/adwaita-icon-theme (Permission denied)

error: unable to unlink old 'Library/Aliases/ag' (Permission denied)

error: unable to unlink old 'Library/Aliases/alut' (Permission denied)

error: unable to unlink old 'Library/Aliases/android' (Permission denied)

error: unable to unlink old 'Library/Aliases/apache-activemq' (Permission denied)

error: unable to unlink old 'Library/Aliases/apache-fop' (Permission denied)

error: unable to create symlink Library/Aliases/atlassian-cli (Permission denied)

。。。。。。

解决:执行命令

Last login: Sat Oct 10 11:09:55 on ttys003

zhong:~ andy$ cd /usr/local/

zhong:local andy$ sudo mv -v Library Library.old

Password:

Library -> Library.old

zhong:local andy$ 

成功

Press RETURN to continue or any other key to abort

==> /usr/bin/sudo /bin/mkdir /Library/Caches/Homebrew

==> /usr/bin/sudo /bin/chmod g+rwx /Library/Caches/Homebrew

==> /usr/bin/sudo /usr/sbin/chown andy /Library/Caches/Homebrew

==> Downloading and installing Homebrew...

remote: Counting objects: 3770, done.

remote: Compressing objects: 100% (3609/3609), done.

remote: Total 3770 (delta 43), reused 539 (delta 26), pack-reused 0

Receiving objects: 100% (3770/3770), 3.21 MiB | 478.00 KiB/s, done.

Resolving deltas: 100% (43/43), done.

From https://github.com/Homebrew/homebrew

 * [new branch]      master     -> origin/master

HEAD is now at 6014053 disktype: fix bottle misplacement

==> Installation successful!

==> Next steps

Run `brew help` to get started


2.创建版本库Excel2Json

zhong:GIT andy$ mkdir Excel2Json

zhong:GIT andy$ cd Excel2Json/

zhong:Excel2Json andy$ pwdpwd:查看当前路径

/Volumes/Macintosh HD/Work/GIT/Excel2Json

zhong:Excel2Json andy$ git init

Initialized empty Git repository in /Volumes/Macintosh HD/Work/GIT/Excel2Json/.git/

zhong:Excel2Json andy$ 

zhong:Excel2Json andy$ ls -ahls -ah:可查看隐藏的文件

. .. .git


3.一些常用命令

第一步,用命令git add告诉Git,把文件添加到仓库:

$ git add readme.txt

执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。

第二步,用命令git commit告诉Git,把文件提交到仓库:

$ git commit -m "wrote a readme file"
[master (root-commit) cb926e7] wrote a readme file
 1 file changed, 2 insertions(+)
 create mode 100644 readme.txt
  • 要随时掌握工作区的状态,使用git status命令。

  • 如果git status告诉你有文件被修改过,用git diff可以查看修改内容。

  • HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id

  • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本

    如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数:

    $ git log --pretty=oneline
    3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
    ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
    cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file

    Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

    现在,我们要把当前版本“append GPL”回退到上一个版本“add distributed”,就可以使用git reset命令:

    $ git reset --hard HEAD^
    HEAD is now at ea34578 add distributed

    commit id3628164...,于是就可以指定回到未来的某个版本:

    $ git reset --hard 3628164
    HEAD is now at 3628164 append GPL
    

    版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。


  • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

    4.工作区和暂存区

    Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
    工作区(Working Directory)

    就是你在电脑里能看到的目录,比如我的Excel2Json文件夹就是一个工作区:

    版本库(Repository)

    工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

    Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

    第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;

    第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

    git checkout -- file可以丢弃工作区的修改:

    撤销修改

    $ git checkout -- readme.txt
    

    命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

    一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

    一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

    总之,就是让这个文件回到最近一次git commitgit add时的状态。

    修改小结

    场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file

    场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。

    场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。

    git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。


    命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容

    5.添加远程库

    已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。

    自行注册GitHub账号。由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置:

    第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsaid_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:

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

    你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。

    如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsaid_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

    第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:

    然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容:


    zhong:~ andy$ ssh-keygen -t rsa -C "zjia5@qq.com"

    Generating public/private rsa key pair.

    Enter file in which to save the key (/Users/andy/.ssh/id_rsa): 

    Enter passphrase (empty for no passphrase): 

    Enter same passphrase again: 

    Your identification has been saved in /Users/andy/.ssh/id_rsa.

    Your public key has been saved in /Users/andy/.ssh/id_rsa.pub.

    The key fingerprint is:

    eb:73:17:e8:2f:a5:b7:4a:4c:e8:c0:22:4f:92:f1:66 zjia5@qq.com

    The key's randomart image is:

    +--[ RSA 2048]----+

    |                 |

    |                 |

    |  .              |

    |   + .   .       |

    |  + E o S ..     |

    |   B . o +. o    |

    |    .   o.oo .   |

    |       ...= o    |

    |        .o.*o.   |

    +-----------------+

    zhong:~ andy$ ls -a

    ..configDesktop

    ...gitconfigDocuments

    .CFUserTextEncoding.gitignore_globalDownloads

    .DS_Store.hgignore_globalLibrary

    .Trash.idlercMovies

    .android.localMusic

    .bash_history.sshPictures

    .bash_profile.subversionPublic

    .bash_profile.pysave.viminfodebug.keystore

    .bash_profile.save.yunpanelipse_workspace

    .bash_profile.swpApplicationsfarm_kona.keystore

    .cacheCocos Studio未命名文件夹

    zhong:~ andy$ cd .ssh/

    zhong:.ssh andy$ ls

    id_rsaid_rsa.pubknown_hosts

    zhong:.ssh andy$ vi id_rsa.pub 

    zhong:.ssh andy$ 


    把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。

    git remote add origin https://github.com/Mr-Zhong/Excel2Json.git
    远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
    
     
      
    把本地仓库的内容推送到GitHub仓库。
    git push -u origin master

    zhong:.ssh andy$ cd /Volumes/Macintosh\ HD/Work/GIT/Excel2Json 

    zhong:Excel2Json andy$ git remote add origin https://github.com/Mr-Zhong/Excel2Json.git


    zhong:Excel2Json andy$ git push -u origin master

    Username for 'https://github.com': zjia5@qq.com

    Password for 'https://zjia5@qq.com@github.com': 

    Counting objects: 21, done.

    Delta compression using up to 4 threads.

    Compressing objects: 100% (19/19), done.

    Writing objects: 100% (21/21), 3.00 MiB | 491.00 KiB/s, done.

    Total 21 (delta 0), reused 0 (delta 0)

    To https://github.com/Mr-Zhong/Excel2Json.git

     * [new branch]      master -> master

    Branch master set up to track remote branch master from origin.

    zhong:Excel2Json andy$ 

    从现在起,只要本地作了提交,就可以通过命令:

    $ git push origin master
    

    把本地master分支的最新修改推送至GitHub,现在,你就拥有了真正的分布式版本库!

    6。克隆远程仓库
    $ git clone git@github.com:michaelliao/gitskills.git

    要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。

    Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。

    GitHub给出的地址不止一个,还可以用https://github.com/michaelliao/gitskills.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。

    使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https

    7.分支

    分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

    现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

    其他版本控制系统如SVN等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。

    但Git的分支是与众不同的,无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。

    首先,我们创建dev分支,然后切换到dev分支:

    $ git checkout -b dev
    Switched to a new branch 'dev'
    

    git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

    $ git branch dev
    $ git checkout dev
    Switched to branch 'dev'
    

    然后,用git branch命令查看当前分支:

    $ git branch
    * dev
      master
    

    git branch命令会列出所有分支,当前分支前面会标一个*号。

    然后,我们就可以在dev分支上正常提交,比如对readme.txt做个修改,加上一行:

    Creating a new branch is quick.
    

    然后提交:

    $ git add readme.txt 
    $ git commit -m "branch test"
    [dev fec145a] branch test
     1 file changed, 1 insertion(+)
    

    现在,dev分支的工作完成,我们就可以切换回master分支:

    $ git checkout master
    Switched to branch 'master'
    

    切换回master分支后,再查看一个readme.txt文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master分支此刻的提交点并没有变:

    git-br-on-master

    现在,我们把dev分支的工作成果合并到master分支上:

    $ git merge dev
    Updating d17efd8..fec145a
    Fast-forward
     readme.txt |    1 +
     1 file changed, 1 insertion(+)
    

    git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

    注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。

    当然,也不是每次合并都能Fast-forward,我们后面会将其他方式的合并。

    合并完成后,就可以放心地删除dev分支了:

    $ git branch -d dev
    Deleted branch dev (was fec145a).
    

    删除后,查看branch,就只剩下master分支了:

    $ git branch
    * master
    

    因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

    小结

    Git鼓励大量使用分支:

    查看分支:git branch

    创建分支:git branch <name>

    切换分支:git checkout <name>

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

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

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

    当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。

    git log --graph命令可以看到分支合并图。

    8.创建标签

    在Git中打标签非常简单,首先,切换到需要打标签的分支上:

    $ git branch
    * dev
      master
    $ git checkout master
    Switched to branch 'master'
    

    然后,敲命令git tag <name>就可以打一个新标签:

    $ git tag v1.0
    

    可以用命令git tag查看所有标签:

    $ git tag
    v1.0
    

    默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?

    方法是找到历史提交的commit id,然后打上就可以了:

    $ git log --pretty=oneline --abbrev-commit
    6a5819e merged bug fix 101
    cc17032 fix bug 101
    7825a50 merge with no-ff
    6224937 add merge
    59bc1cb conflict fixed
    400b400 & simple
    75a857c AND simple
    fec145a branch test
    d17efd8 remove test.txt
    ...
    

    比方说要对add merge这次提交打标签,它对应的commit id是6224937,敲入命令:

    $ git tag v0.9 6224937
    

    再用命令git tag查看标签:

    $ git tag
    v0.9
    v1.0
    

    注意,标签不是按时间顺序列出,而是按字母排序的。可以用git show <tagname>查看标签信息:

    $ git show v0.9
    commit 622493706ab447b6bb37e4e2a2f276a20fed2ab4
    Author: Michael Liao <askxuefeng@gmail.com>
    Date:   Thu Aug 22 11:22:08 2013 +0800
    
        add merge
    ...
    

    可以看到,v0.9确实打在add merge这次提交上。

    还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:

    $ git tag -a v0.1 -m "version 0.1 released" 3628164
    

    用命令git show <tagname>可以看到说明文字:

    $ git show v0.1
    tag v0.1
    Tagger: Michael Liao <askxuefeng@gmail.com>
    Date:   Mon Aug 26 07:28:11 2013 +0800
    
    version 0.1 released
    
    commit 3628164fb26d48395383f8f31179f24e0882e1e0
    Author: Michael Liao <askxuefeng@gmail.com>
    Date:   Tue Aug 20 15:11:49 2013 +0800
    
        append GPL
    

    还可以通过-s用私钥签名一个标签:

    $ git tag -s v0.2 -m "signed version 0.2 released" fec145a
    

    签名采用PGP签名,因此,必须首先安装gpg(GnuPG),如果没有找到gpg,或者没有gpg密钥对,就会报错:

    gpg: signing failed: secret key not available
    error: gpg failed to sign the data
    error: unable to sign the tag
    

    如果报错,请参考GnuPG帮助文档配置Key。

    用命令git show <tagname>可以看到PGP签名信息:

    $ git show v0.2
    tag v0.2
    Tagger: Michael Liao <askxuefeng@gmail.com>
    Date:   Mon Aug 26 07:28:33 2013 +0800
    
    signed version 0.2 released
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.12 (Darwin)
    
    iQEcBAABAgAGBQJSGpMhAAoJEPUxHyDAhBpT4QQIAKeHfR3bo...
    -----END PGP SIGNATURE-----
    
    commit fec145accd63cdc9ed95a2f557ea0658a2a6537f
    Author: Michael Liao <askxuefeng@gmail.com>
    Date:   Thu Aug 22 10:37:30 2013 +0800
    
        branch test
    

    用PGP签名的标签是不可伪造的,因为可以验证PGP签名。验证签名的方法比较复杂,这里就不介绍了。

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

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

    • git tag -s <tagname> -m "blablabla..."可以用PGP签名标签;

    • 命令git tag可以查看所有标签。

    操作标签

    如果标签打错了,也可以删除:

    $ git tag -d v0.1
    Deleted tag 'v0.1' (was e078af9)
    

    因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。

    如果要推送某个标签到远程,使用命令git push origin <tagname>

    $ git push origin v1.0
    Total 0 (delta 0), reused 0 (delta 0)
    To git@github.com:michaelliao/learngit.git
     * [new tag]         v1.0 -> v1.0
    

    或者,一次性推送全部尚未推送到远程的本地标签:

    $ git push origin --tags
    Counting objects: 1, done.
    Writing objects: 100% (1/1), 554 bytes, done.
    Total 1 (delta 0), reused 0 (delta 0)
    To git@github.com:michaelliao/learngit.git
     * [new tag]         v0.2 -> v0.2
     * [new tag]         v0.9 -> v0.9
    

    如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

    $ git tag -d v0.9
    Deleted tag 'v0.9' (was 6224937)
    

    然后,从远程删除。删除命令也是push,但是格式如下:

    $ git push origin :refs/tags/v0.9
    To git@github.com:michaelliao/learngit.git
     - [deleted]         v0.9
    

    要看看是否真的从远程库删除了标签,可以登陆GitHub查看。

    9.搭建Git服务器


    GitHub就是一个免费托管开源代码的远程仓库。但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓库使用。

    搭建Git服务器需要准备一台运行Linux的机器,强烈推荐用Ubuntu或Debian,这样,通过几条简单的apt命令就可以完成安装。

    假设你已经有sudo权限的用户账号,下面,正式开始安装。

    第一步,安装git

    $ sudo apt-get install git
    

    第二步,创建一个git用户,用来运行git服务:

    $ sudo adduser git
    

    第三步,创建证书登录:

    收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

    第四步,初始化Git仓库:

    先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:

    $ sudo git init --bare sample.git
    

    Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git

    $ sudo chown -R git:git sample.git
    

    第五步,禁用shell登录:

    出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:

    git:x:1001:1001:,,,:/home/git:/bin/bash
    

    改为:

    git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
    

    这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

    第六步,克隆远程仓库:

    现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:

    $ git clone git@server:/srv/sample.git
    Cloning into 'sample'...
    warning: You appear to have cloned an empty repository.
    

    剩下的推送就简单了。

    管理公钥

    如果团队很小,把每个人的公钥收集起来放到服务器的/home/git/.ssh/authorized_keys文件里就是可行的。如果团队有几百号人,就没法这么玩了,这时,可以用Gitosis来管理公钥。

    这里我们不介绍怎么玩Gitosis了,几百号人的团队基本都在500强了,相信找个高水平的Linux管理员问题不大。

    管理权限

    有很多不但视源代码如生命,而且视员工为窃贼的公司,会在版本控制系统里设置一套完善的权限控制,每个人是否有读写权限会精确到每个分支甚至每个目录下。因为Git是为Linux源代码托管而开发的,所以Git也继承了开源社区的精神,不支持权限控制。不过,因为Git支持钩子(hook),所以,可以在服务器端编写一系列脚本来控制提交等操作,达到权限控制的目的。Gitolite就是这个工具。

    这里我们也不介绍Gitolite了,不要把有限的生命浪费到权限斗争中。

    小结

    • 搭建Git服务器非常简单,通常10分钟即可完成;

    • 要方便管理公钥,用Gitosis

    • 要像SVN那样变态地控制权限,用Gitolite

    原文地址:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值