什么是 Git

概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0QHGrVwj-1585931055193)(GitLab/f7246b600c338744a9591cd7530fd9f9d62aa0f8.png)]

  • Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
  • Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
  • Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。

安装 Git

下载

下载地址:https://git-scm.com/downloads

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZsE6mVoD-1585931055199)(GitLab/Lusifer1511792517.png)]

安装

双击安装文件,然后出现安装向导界面,点击下一步(Next)即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kD9DU0SA-1585931055202)(GitLab/02_WizardNext.png)]

接着出现授权信息界面, Next即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AzqSkkmH-1585931055203)(GitLab/03_LicenceNext.png)]

选择安装路径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wYOzvTVF-1585931055208)(GitLab/04_InstallPath.png)]

选择文件关联,如果你不清楚,直接默认,下一步即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m0XrEr5B-1585931055209)(GitLab/05_Associate.png)]

接着出现开始菜单文件夹,默认,下一步即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9qCylHxn-1585931055210)(GitLab/06_StartMenu.png)]

然后是是否配置Path的配置,选择中间一个,可以通过 Windows命令行(CMD)调用 git 命令。 然后点击下一步

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LLAYWZce-1585931055210)(GitLab/07_GitPath.png)]

选择回车换行的格式。默认即可.(检出时转换为Windows风格,提交时转换为Linux风格.)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tjHuPvsq-1585931055211)(GitLab/08_CRLF.png)]

然后是安装进度界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J4sJuFBC-1585931055212)(GitLab/09_Installing.png)]

安装完成. 去掉那个查看版本说明的复选框,点击完成(Finish)按钮即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rn5MX9aL-1585931055213)(GitLab/10_Finish.png)]

可以在cmd里面测试是否设置了Path,是否安装成功. 在CMD中输入 git 或者 git --version 试试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rQhOcoJy-1585931055213)(GitLab/1584352474626.png)]

Git 的一般工作流程

  • 克隆 Git 资源作为工作目录。
  • 在克隆的资源上添加或修改文件。
  • 如果其他人修改了,你可以更新资源。
  • 在提交前查看修改。
  • 提交修改。
  • 在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dpTdSLia-1585931055214)(GitLab/git-process.png)]

Git 的基本操作

基本命令

git help

git help
git help -a
	:f下一页
	:b上一页
	:q退出
git help -g
git help add

若你使用 Git 时需要获取帮助,有三种等价的方法可以找到 Git 命令的综合手册(manpage)

$ git help <verb>
$ git <verb> --help
$ man git-<verb>

例如,要想获得 git config 命令的手册,执行

$ git help config

这些命令很棒,因为你随时随地可以使用而无需联网。 如果你觉得手册或者本书的内容还不够用,你可以尝试在 Freenode IRC 服务器 https://freenode.net 上的 #git#github 频道寻求帮助。 这些频道经常有上百人在线,他们都精通 Git 并且乐于助人。

此外,如果你不需要全面的手册,只需要可用选项的快速参考,那么可以用 -h 选项获得更简明的 “help” 输出:

$ git add -h
usage: git add [<options>] [--] <pathspec>...

    -n, --dry-run         dry run
    -v, --verbose         be verbose

    -i, --interactive     interactive picking
    -p, --patch           select hunks interactively
    -e, --edit            edit current diff and apply
    -f, --force           allow adding otherwise ignored files
    -u, --update          update tracked files
    --renormalize         renormalize EOL of tracked files (implies -u)
    -N, --intent-to-add   record only the fact that the path will be added later
    -A, --all             add changes from all tracked and untracked files
    --ignore-removal      ignore paths removed in the working tree (same as --no-all)
    --refresh             don't add, only refresh the index
    --ignore-errors       just skip files which cannot be added because of errors
    --ignore-missing      check if - even missing - files are ignored in dry run
    --chmod (+|-)x        override the executable bit of the listed files

git config

git config --global user.name ""
git config --global user.email ""
git config --list 或者 cat ~/.gitconfig

获取与创建项目命令

git init

用 git init 在目录中创建新的 Git 仓库。 你可以在任何时候、任何目录中这么做,完全是本地化的。

git init

git clone

使用 git clone 拷贝一个 Git 仓库到本地,让自己能够查看该项目,或者进行修改。

git clone [url]

基本快照

git add

git add 命令可将该文件添加到缓存

git add <filename>

git status

git status 以查看在你上次提交之后是否有修改。

git status
git status -s

git diff

执行 git diff 来查看执行 git status 的结果的详细信息。

git diff 命令显示已写入缓存与已修改但尚未写入缓存的改动的区别。git diff 有两个主要的应用场景。

  • 尚未缓存的改动:git diff
  • 查看已缓存的改动: git diff --cached
  • 查看已缓存的与未缓存的所有改动:git diff HEAD
  • 显示摘要而非整个 diff:git diff --stat

git commit

使用 git add 命令将想要快照的内容写入缓存区, 而执行 git commit 将缓存区内容添加到仓库中。

Git 为你的每一个提交都记录你的名字与电子邮箱地址,所以第一步需要配置用户名和邮箱地址。

git config --global user.name 'yourname'
git config --global user.email youremail

将文件写入缓存区并提供提交注释

git commit -m 'update message'

git reset HEAD

git reset HEAD 命令用于取消已缓存的内容。

git reset HEAD -- <filename>

拉取与推送

git pull

git pull命令用于从另一个存储库或本地分支获取并集成(整合)。git pull命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并,它的完整格式稍稍有点复杂。

git pull <远程主机名> <远程分支名>:<本地分支名>

将远程存储库中的更改合并到当前分支中。在默认模式下,git pullgit fetch后跟git merge FETCH_HEAD的缩写。更准确地说,git pull使用给定的参数运行git fetch,并调用git merge将检索到的分支头合并到当前分支中。

git push

git push命令用于将本地分支的更新,推送到远程主机。它的格式与git pull命令相似。

git push <远程主机名> <本地分支名>:<远程分支名>

标签

git tag

如果你达到一个重要的阶段,并希望永远记住那个特别的提交快照,你可以使用 git tag 给它打上标签。

比如说,我们想为我们的 商城 项目发布一个"1.0.0"版本。 我们可以用 git tag -a v1.0.0 命令给最新一次提交打上(HEAD) “v1.0.0” 的标签。

-a 选项意为"创建一个带注解的标签"。 不用 -a 选项也可以执行的,但它不会记录这标签是啥时候打的,谁打的,也不会让你添加个标签的注解。 我推荐一直创建带注解的标签。

git tag -a v1.0.0

如果我们要查看所有标签可以使用以下命令:

git tag

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab
$ mkdir git-demo

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab
$ ll
total 40
drwxr-xr-x 1 13512 197121     0  3月 16 21:13 git-demo/
drwxr-xr-x 1 13512 197121     0  3月 16 20:05 GitLab/
-rw-r--r-- 1 13512 197121 21526  3月 16 19:56 GitLab.md
drwxr-xr-x 1 13512 197121     0  3月 16 18:06 tools/

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab
$ cd git-demo/

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo
$ git init
Initialized empty Git repository in D:/youruike/GitLab/git-demo/.git/

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ ll
total 0

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ ll
total 0

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ touch README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ ll
total 0
-rw-r--r-- 1 13512 197121 0  3月 16 21:17 README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        README.md

nothing added to commit but untracked files present (use "git add" to track)

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git add README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md


13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git rm --cached README.md
rm 'README.md'

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        README.md

nothing added to commit but untracked files present (use "git add" to track)

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git add -A

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md


13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ ll
total 0
-rw-r--r-- 1 13512 197121 0  3月 16 21:17 README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ ll -la
total 4
drwxr-xr-x 1 13512 197121 0  3月 16 21:17 ./
drwxr-xr-x 1 13512 197121 0  3月 16 21:13 ../
drwxr-xr-x 1 13512 197121 0  3月 16 21:23 .git/
-rw-r--r-- 1 13512 197121 0  3月 16 21:17 README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ cd .git/

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo/.git (GIT_DIR!)
$ ls
config  description  HEAD  hooks/  index  info/  objects/  refs/

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo/.git (GIT_DIR!)
$ ll
total 8
-rw-r--r-- 1 13512 197121 130  3月 16 21:16 config
-rw-r--r-- 1 13512 197121  73  3月 16 21:16 description
-rw-r--r-- 1 13512 197121  23  3月 16 21:16 HEAD
drwxr-xr-x 1 13512 197121   0  3月 16 21:16 hooks/
-rw-r--r-- 1 13512 197121 104  3月 16 21:22 index
drwxr-xr-x 1 13512 197121   0  3月 16 21:16 info/
drwxr-xr-x 1 13512 197121   0  3月 16 21:20 objects/
drwxr-xr-x 1 13512 197121   0  3月 16 21:16 refs/

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo/.git (GIT_DIR!)
$ cat index
DIRC^o|o9rh<^o|o9z▒0▒▒▒⛲▒▒CK▒)▒wZ▒▒▒S▒ README.md▒▒▒▒O  ▒
                                                         vN▒nr▒E▒
13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo/.git (GIT_DIR!)
$ cd ..

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ ls
README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git commit help
error: pathspec 'help' did not match any file(s) known to git

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git commit -m "i add README.md"
[master (root-commit) a5b1a1f] i add README.md
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git remote add origin https://github.com/ange-six/git-demo.git

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git remote -v
origin  https://github.com/ange-six/git-demo.git (fetch)
origin  https://github.com/ange-six/git-demo.git (push)

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git push -u origin master
To https://github.com/ange-six/git-demo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/ange-six/git-demo.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.

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git pull --rebase origin master
warning: no common commits
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), done.
From https://github.com/ange-six/git-demo
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
First, rewinding head to replay your work on top of it...
Applying: i add README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git push -u origin master
fatal: HttpRequestException encountered.
   ▒▒▒▒▒▒▒▒ʱ▒▒▒▒
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 6 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 311 bytes | 311.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/ange-six/git-demo.git
   0e5f771..0589a86  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
---------------------------------------------------------------------------------------
13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab
$ git clone https://github.com/ange-six/git-demo.git git-mydemo
Cloning into 'git-mydemo'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 7 (delta 1), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (7/7), done.

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab
$ cd git-mydemo/

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ ls
LICENSE  README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ vi README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ vi README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ 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:   README.md

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

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ git add -A
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   README.md


13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ git commit -m "i update README.md"
[master cd82ad4] i update README.md
 1 file changed, 1 insertion(+)

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ git remote -v
origin  https://github.com/ange-six/git-demo.git (fetch)
origin  https://github.com/ange-six/git-demo.git (push)

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ git push -u origin master
fatal: HttpRequestException encountered.
   ▒▒▒▒▒▒▒▒ʱ▒▒▒▒
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/ange-six/git-demo.git/'

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ git push -u origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 6 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 256 bytes | 256.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/ange-six/git-demo.git
   0589a86..cd82ad4  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-mydemo (master)
$ cd ..

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab
$ ls
git-demo/  GitLab/  GitLab.md  git-mydemo/  tools/

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab
$ cd git-demo/

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ ls
LICENSE  README.md

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/ange-six/git-demo
   0589a86..cd82ad4  master     -> origin/master
Updating 0589a86..cd82ad4
Fast-forward
 README.md | 1 +
 1 file changed, 1 insertion(+)

13512@DESKTOP-SCIVEHJ MINGW64 /d/youruike/GitLab/git-demo (master)
$


TortoiseGit 简化 Git 操作

下载

下载地址:https://tortoisegit.org/download/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gQOErEZV-1585931055218)(GitLab/Lusifer1511792468-1584353014512.png)]

安装

我们需要先安装程序包,然后安装语言包(LanguagePack). 因为TortoiseGit 只是一个程序壳,必须依赖一个 Git Core,也就是上一节我们安装的 Git. 所以安装前请确定已完成上一节的操作. 下面以64位版本为演示(64,32位除文件名不一样,其他的操作都一致)

  • 双击安装程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Drhtcjo-1585931055219)(GitLab/203_tgitWizard-1584353014648.png)]

  • 下一步,进入版权信息界面. 直接点击下一步(Next)即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gSL1iugo-1585931055220)(GitLab/204_tgit_License-1584353014670.png)]

  • 下一步,选择SSH客户端. 可以选择 TortoiseGitPlink(位于TortoiseGit安装目录/bin 下), 也可以选择 Git 默认的SSH客户端,位于 Git安装目录/bin/ssh.exe(如果配置了 Path,那直接是 ssh.exe)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fY0xGiRj-1585931055221)(GitLab/204_2_tgit_Network-1584353014670.png)]

  • 接着是选择安装目录,可以保持默认,或者安装到开发环境目录下,安装的程序组件保持默认即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4jtK9VfP-1585931055222)(GitLab/205_tgit_dir-1584353014670.png)]

  • 下一步到确认安装界面,点击 Install按钮安装即可,如下图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yVdsQIP3-1585931055223)(GitLab/206_install_tgit-1584353014671.png)]

  • 安装完成,点击 Finish 按钮即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I4DcXPDc-1585931055224)(GitLab/207_tgit_installed-1584353014671.png)]

安装语言包

双击打开语言包安装程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q1LHc3xI-1585931055225)(GitLab/208_LanguageWizard-1584353014671.png)]

点击下一步(Alt+N), 语言包会自动安装完成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NEhevJWo-1585931055226)(GitLab/209_LangPackFinished-1584353014671.png)]

配置

在空白处点击鼠标右键, 选择 --> TortoiseGit --> Settings, 然后就可以看到配置界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jK4N0xFX-1585931055226)(GitLab/Lusifer1511793790-1584353014671.png)]

选中General,在右边的 Language中选择中文. 不勾选自动升级的复选框,可能还需要指定 Git.exe 文件的路径

再次点击鼠标右键,可以看到弹出菜单中已经变成中文. 原来的 Settings 变成 设置; Clone 变为 克隆

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zp3RJnNM-1585931055230)(GitLab/Lusifer1511793872-1584353014671.png)]

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐