From ab9484a32b1b03f025e2ae158dbd42205e4750bb Mon Sep 17 00:00:00 2001 From: robot527 Date: Wed, 12 Apr 2017 22:32:41 +0800 Subject: [PATCH 01/37] [GDB common commands] translated and edited by robot527 --- translated/tech/GDB-common-commands.md | 259 +++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 translated/tech/GDB-common-commands.md diff --git a/translated/tech/GDB-common-commands.md b/translated/tech/GDB-common-commands.md new file mode 100644 index 0000000000..cdf7430529 --- /dev/null +++ b/translated/tech/GDB-common-commands.md @@ -0,0 +1,259 @@ +#常用的 GDB 命令中文释义 + +## 目录 + + - [break](#break) -- 缩写 `b`,在指定的行或函数处设置断点 + - [info breakpoints](#info-breakpoints) -- 简写 `i b`,打印未删除的所有断点,观察点和捕获点的列表 + - [disable](#disable) -- 禁用断点,可以缩写为 `dis` + - [enable](#enable) -- 启用断点 + - [clear](#clear) -- 清除指定行或函数处的断点 + - [delete](#delete) -- 缩写 `d`,删除断点 + - [tbreak](#tbreak) -- 设置临时断点,参数同 `break`,但在程序第一次停住后会被自动删除 + - [watch](#watch) -- 为表达式(或变量)设置观察点,当表达式(或变量)的值有变化时,停住程序 + + - [step](#step) -- 缩写 `s`,单步跟踪,如果有函数调用,会进入该函数 + - [reverse-step](#reverse-step) -- 反向单步跟踪,如果有函数调用,会进入该函数 + - [next](#next) -- 缩写 `n`,单步跟踪,如果有函数调用,不会进入该函数 + - [reverse-next](#reverse-next) -- 反向单步跟踪,如果有函数调用,不会进入该函数 + - [return](#return) -- 使选定的栈帧返回到其调用者 + - [finish](#finish) -- 缩写 `fin`,执行直到选择的栈帧返回 + - [until](#until) -- 缩写 `u`,执行直到...(用于跳过循环、递归函数调用) + - [continue](#continue) -- 同义词 `c`,恢复程序执行 + + - [print](#print) -- 缩写 `p`,打印表达式 EXP 的值 + - [x](#x) -- 查看内存 + + - [display](#display) -- 每次程序停止时打印表达式 EXP 的值(自动显示) + - [info display](#info-display) -- 打印早先设置为自动显示的表达式列表 + - [disable display](#disable-display) -- 禁用自动显示 + - [enable display](#enable-display) -- 启用自动显示 + - [undisplay](#undisplay) -- 删除自动显示项 + + - [help](#help) -- 缩写 `h`,打印命令列表(带参数时查找命令的帮助) + + - [attach](#attach) -- 挂接到已在运行的进程来调试 + - [run](#run) -- 缩写 `r`,启动被调试的程序 + + - [backtrace](#backtrace) -- 缩写 `bt`,查看程序调用栈的信息 + + +************ + +## break +使用 `break` 命令(缩写 `b`)来设置断点。 参见[官方文档][1]。 + + - `break` 当不带参数时,在所选栈帧中执行的下一条指令处设置断点。 + - `break ` 在函数体入口处打断点,在 C++ 中可以使用 `class::function` 或 `function(type, ...)` 格式来指定函数名。 + - `break ` 在当前源码文件指定行的开始处打断点。 + - `break -N` `break +N` 在当前源码行前面或后面的 `N` 行开始处打断点,`N` 为正整数。 + - `break ` 在源码文件 `filename` 的 `linenum` 行处打断点。 + - `break ` 在源码文件 `filename` 的 `function` 函数入口处打断点。 + - `break
` 在程序指令的地址处打断点。 + - `break ... if ` 设置条件断点,`...` 代表上述参数之一(或无参数),`cond` 为条件表达式,仅在 `cond` 值非零时停住程序。 + +## info breakpoints +查看断点,观察点和捕获点的列表。用法: +`info breakpoints [list…]` +`info break [list…]` +`list…` 用来指定若干个断点的编号(可省略),可以是 `2`, `1-3`, `2 5` 等。 + +## disable +禁用一些断点。 参见[官方文档][2]。 +参数是用空格分隔的断点编号。 +要禁用所有断点,不加参数。 +禁用的断点不会被忘记,但直到重新启用才有效。 +用法: `disable [breakpoints] [list…]` +`breakpoints` 是 `disable` 的子命令(可省略),`list…` 同 `info breakpoints` 中的描述。 + +## enable +启用一些断点。 参见[官方文档][2]。 +给出断点编号(以空格分隔)作为参数。 +没有参数时,所有断点被启用。 + + - `enable [breakpoints] [list…]` 启用指定的断点(或所有定义的断点)。 + - `enable [breakpoints] once list…` 临时启用指定的断点。GDB 在停止您的程序后立即禁用这些断点。 + - `enable [breakpoints] delete list…` 使指定的断点启用一次,然后删除。一旦您的程序停止,GDB 就会删除这些断点。等效于用 `tbreak` 设置的断点。 + +`breakpoints` 同 `disable` 中的描述。 + +## clear +在指定行或函数处清除断点。 参见[官方文档][3]。 +参数可以是行号,函数名称或 "*" 跟一个地址。 + + - `clear` 当不带参数时,清除所选栈帧在执行的源码行中的所有断点。 + - `clear `, `clear ` 删除在命名函数的入口处设置的任何断点。 + - `clear `, `clear ` 删除在指定的文件指定的行号的代码中设置的任何断点。 + - `clear
` 清除指定程序指令的地址处的断点。 + +## delete +删除一些断点或自动显示表达式。 参见[官方文档][3]。 +参数是用空格分隔的断点编号。 +要删除所有断点,不加参数。 +用法: `delete [breakpoints] [list…]` + +## tbreak +设置临时断点。参数形式同 `break` 一样。 参见[官方文档][1]。 +除了断点是临时的之外像 `break` 一样,所以在命中时会被删除。 + +## watch +为表达式设置观察点。 参见[官方文档][4]。 +用法: `watch [-l|-location] ` +每当一个表达式的值改变时,观察点就会停止执行您的程序。 +如果给出了 `-l` 或者 `-location`,则它会对 `expr` 求值并观察它所指向的内存。 +例如,`watch *(int *)0x12345678` 将在指定的地址处观察一个 4 字节的区域(假设 int 占用 4 个字节)。 + +## step +单步执行程序,直到到达不同的源码行。 参见[官方文档][5]。 +用法: `step [N]` +参数 `N` 表示执行 N 次(或由于另一个原因直到程序停止)。 +警告:如果当控制在没有调试信息的情况下编译的函数中使用 `step` 命令,则执行将继续进行, +直到控制到达具有调试信息的函数。 同样,它不会进入没有调试信息编译的函数。 +要执行没有调试信息的函数,请使用 `stepi` 命令,后文再述。 + +## reverse-step +反向步进程序,直到到达另一个源码行的开头。 参见[官方文档][6]。 +用法: `reverse-step [N]` +参数 `N` 表示执行 N 次(或由于另一个原因直到程序停止)。 + +## next +单步执行程序,执行完子程序调用。 参见[官方文档][5]。 +用法: `next [N]` +与 `step` 不同,如果当前的源代码行调用子程序,则此命令不会进入子程序,而是继续执行,将其视为单个源代码行。 + +## reverse-next +反向步进程序,执行完子程序调用。 参见[官方文档][6]。 +用法: `reverse-next [N]` +如果要执行的源代码行调用子程序,则此命令不会进入子程序,调用被视为一个指令。 +参数 `N` 表示执行 N 次(或由于另一个原因直到程序停止)。 + +## return +您可以使用 `return` 命令取消函数调用的执行。 参见[官方文档][7]。 +如果你给出一个表达式参数,它的值被用作函数的返回值。 +`return ` 将 `expression` 的值作为函数的返回值并使函数直接返回。 + +## finish +执行直到选定的栈帧返回。 参见[官方文档][5]。 +用法: `finish` +返回后,返回的值将被打印并放入到值历史记录中。 + +## until +执行直到程序到达大于当前栈帧或当前栈帧中的指定位置(与 [break](#break) 命令相同的参数)的源码行。 参见[官方文档][5]。 +此命令用于通过一个多次的循环,以避免单步执行。 +`until ` 或 `u ` 继续运行程序,直到达到指定的位置,或者当前栈帧返回。 + +## continue +在信号或断点之后,继续运行被调试的程序。 参见[官方文档][5]。 +用法: `continue [N]` +如果从断点开始,可以使用数字 `N` 作为参数,这意味着将该断点的忽略计数设置为 `N - 1`(以便断点在第 N 次到达之前不会中断)。 +如果启用了非停止模式(使用 `show non-stop` 查看),则仅继续当前线程,否则程序中的所有线程都将继续。 + +## print +求值并打印表达式 EXP 的值。 参见[官方文档][8]。 +可访问的变量是所选栈帧的词法环境,以及范围为全局或整个文件的所有变量。 +用法: `print [expr]` 或 `print /f [expr]` +`expr` 是一个(在源代码语言中的)表达式。 +默认情况下,`expr` 的值以适合其数据类型的格式打印;您可以通过指定 `/f` 来选择不同的格式,其中 `f` 是一个指定格式的字母;参见[输出格式][9]。 +如果省略 `expr`,GDB 再次显示最后一个值。 + +## x +检查内存。 参见[官方文档][10]。 +用法: `x/nfu ` 或 `x ` +`n`, `f`, 和 `u` 都是可选参数,用于指定要显示的内存以及如何格式化。 +`addr` 是要开始显示内存的地址的表达式。 +`n` 重复次数(默认值是 1),指定要显示多少个单位(由 `u` 指定)的内存值。 +`f` 显示格式(初始默认值是 `x`),显示格式是 `print('x','d','u','o','t','a','c','f','s')` 使用的格式之一,再加 `i`(机器指令)。 +`u` 单位大小,`b` 表示单字节,`h` 表示双字节,`w` 表示四字节,`g` 表示八字节。 +例如,`x/3uh 0x54320` 表示从地址 0x54320 开始以无符号十进制整数的方式,双字节为单位显示 3 个内存值。 + +## display +每次程序停止时打印表达式 EXP 的值。 参见[官方文档][11]。 +用法: `display `, `display/fmt ` 或 `display/fmt ` +`fmt` 用于指定显示格式。像 [print](#print) 命令里的 `/f` 一样。 +对于格式 `i` 或 `s`,或者包括单位大小或单位数量,将表达式 `addr` 添加为每次程序停止时要检查的内存地址。 + +## info display +打印自动显示的表达式列表,每个表达式都带有项目编号,但不显示其值。 +包括被禁用的表达式和不能立即显示的表达式(当前不可用的自动变量)。 + +## undisplay +取消某些表达式在程序停止时自动显示。 +参数是表达式的编号(使用 `info display` 查询编号)。 +不带参数表示取消所有自动显示表达式。 +`delete display` 具有与此命令相同的效果。 + +## disable display +禁用某些表达式在程序停止时自动显示。 +禁用的显示项目不会被自动打印,但不会被忘记。 它可能稍后再次被启用。 +参数是表达式的编号(使用 `info display` 查询编号)。 +不带参数表示禁用所有自动显示表达式。 + +## enable display +启用某些表达式在程序停止时自动显示。 +参数是重新显示的表达式的编号(使用 `info display` 查询编号)。 +不带参数表示启用所有自动显示表达式。 + +## help +打印命令列表。 参见[官方文档][12]。 +您可以使用不带参数的 `help`(缩写为 `h`)来显示命令的类别名的简短列表。 +使用 `help ` 您可以获取该类中各个命令的列表。 +使用 `help ` 显示如何使用该命令的简述。 + +## attach +挂接到 GDB 之外的进程或文件。 参见[官方文档][13]。 +该命令可以将进程 ID 或设备文件作为参数。 +对于进程 ID,您必须具有向进程发送信号的权限,并且必须具有与调试器相同的有效的 uid。 +用法: `attach ` +GDB 在安排调试指定的进程之后做的第一件事是停住它。 +您可以使用所有通过 `run` 命令启动进程时可以使用的 GDB 命令来检查和修改挂接的进程。 + +## run +启动被调试的程序。 参见[官方文档][14]。 +可以直接指定参数,也可以用 [set args][15] 设置(启动所需的)参数。 +例如: `run arg1 arg2 ...` 等效于 +``` +set args arg1 arg2 ... +run +``` +还允许使用 ">", "<", 或 ">>" 进行输入和输出重定向。 + +## backtrace +打印整个栈的回溯。 参见[官方文档][16]。 + + - `bt` 打印整个栈的回溯,每个栈帧一行。 + - `bt n` 类似于上,但只打印最内层的 n 个栈帧。 + - `bt -n` 类似于上,但只打印最外层的 n 个栈帧。 + - `bt full n` 类似于 `bt n`,还打印局部变量的值。 + +`where` 和 `info stack`(缩写 `info s`) 是 `backtrace` 的别名。 + +************ + +## 参考资料 + + - [Debugging with GDB](https://sourceware.org/gdb/current/onlinedocs/gdb/) + - [用 GDB 调试程序(二)](http://blog.csdn.net/haoel/article/details/2880) + +-------------------------------------------------------------------------------- + +编译者:[robot527](https://github.com/robot527) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[1]:https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Breaks.html +[2]:https://sourceware.org/gdb/current/onlinedocs/gdb/Disabling.html +[3]:https://sourceware.org/gdb/current/onlinedocs/gdb/Delete-Breaks.html +[4]:https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Watchpoints.html +[5]:https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html +[6]:https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html +[7]:https://sourceware.org/gdb/current/onlinedocs/gdb/Returning.html +[8]:https://sourceware.org/gdb/current/onlinedocs/gdb/Data.html +[9]:https://sourceware.org/gdb/current/onlinedocs/gdb/Output-Formats.html +[10]:https://sourceware.org/gdb/current/onlinedocs/gdb/Memory.html +[11]:https://sourceware.org/gdb/current/onlinedocs/gdb/Auto-Display.html +[12]:https://sourceware.org/gdb/current/onlinedocs/gdb/Help.html +[13]:https://sourceware.org/gdb/current/onlinedocs/gdb/Attach.html +[14]:https://sourceware.org/gdb/current/onlinedocs/gdb/Starting.html +[15]:https://sourceware.org/gdb/current/onlinedocs/gdb/Arguments.html +[16]:https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html + From 0f7304f8e0ed3b0249bc966327818c977f2f6f29 Mon Sep 17 00:00:00 2001 From: robot527 Date: Thu, 13 Apr 2017 10:24:23 +0800 Subject: [PATCH 02/37] updated GDB common commands --- translated/tech/GDB-common-commands.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translated/tech/GDB-common-commands.md b/translated/tech/GDB-common-commands.md index cdf7430529..4ba6de54ef 100644 --- a/translated/tech/GDB-common-commands.md +++ b/translated/tech/GDB-common-commands.md @@ -1,4 +1,4 @@ -#常用的 GDB 命令中文释义 +# 常用的 GDB 命令中文释义 ## 目录 From acc673f38ab2d1fb010655c008863e8f6bd3ce26 Mon Sep 17 00:00:00 2001 From: chenxinlong <237448382@qq.com> Date: Thu, 13 Apr 2017 23:33:31 +0800 Subject: [PATCH 03/37] translating by chenxinlong --- sources/tech/20170317 AWS cloud terminology.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sources/tech/20170317 AWS cloud terminology.md b/sources/tech/20170317 AWS cloud terminology.md index 0f38aafd61..8cdcb0af89 100644 --- a/sources/tech/20170317 AWS cloud terminology.md +++ b/sources/tech/20170317 AWS cloud terminology.md @@ -1,3 +1,4 @@ +translating by chenxinlong AWS cloud terminology ============================================================ @@ -17,7 +18,7 @@ As of today, AWS offers total of 71 services which are grouped together in * * * - _Compute _ + _Compute_ Its a cloud computing means virtual server provisioning. This group provides below services. @@ -210,7 +211,7 @@ Its desktop app streaming over cloud. via: http://kerneltalks.com/virtualization/aws-cloud-terminology/ 作者:[Shrikant Lavhate][a] -译者:[译者ID](https://github.com/译者ID) +译者:[chenxinlong](https://github.com/chenxinlong) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 6e75e79bc696e31da32cbc70d69ffa8094912067 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 14 Apr 2017 16:17:33 +0800 Subject: [PATCH 04/37] PRF&PUB:20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md @GitFuture --- ...ing visual diffmerge tool Meld on Linux.md | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) rename {translated/tech => published}/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md (76%) diff --git a/translated/tech/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md b/published/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md similarity index 76% rename from translated/tech/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md rename to published/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md index aca65df359..401235218c 100644 --- a/translated/tech/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md +++ b/published/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md @@ -1,24 +1,17 @@ -Linux 系统可视化的比较与合并工具 Meld 的新手使用教程 +Linux 系统上的可视化比较与合并工具 Meld ============================================================ -### 本页内容 - -1. [关于 Meld][1] -2. [安装 Meld][2] -3. [使用 Meld][3] -4. [总结][4] - -我们已经[讲过][5] Linux 中[一些][6]基于命令行的比较和合并工具,再来讲解该系统的一些可视化的比较与合并工具也很合理。首要的原因是,不是每个人都习惯使用命令行,而且对于某些人来说,基于命令行的比较工具可能很难学习和理解。 +我们已经[讲过][5] Linux 中[一些][6]基于命令行的比较和合并工具,再来讲解该系统的一些可视化的比较与合并工具也很合理。首要的原因是,不是每个人都习惯使用命令行,而且对于某些人来说,基于命令行的比较工具可能很难学习和理解。 因此,我们将会推出关于可视化工具 **Meld** 的系列文章。 -在跳到安装和介绍部分前,分享这篇教程所有指令和用例是很有用的,而且它们已经在 Ubuntu 14.04 中测试过了,我们使用的 Meld 版本是 3.14.2。 +在跳到安装和介绍部分前,我需要说明这篇教程里所有的指令和用例是都是可用的,而且它们已经在 Ubuntu 14.04 中测试过了,我们使用的 Meld 版本是 3.14.2。 ### 关于 Meld -[Meld][7] 主要是一个可视化的比较和合并的工具,目标人群是开发者(当然,我们将要讲到的其它部分也会考虑到终端用户)。这个工具同时支持双向和三向的比较,不仅仅是比较文件,还可以比较目录,以及版本控制的项目。 +[Meld][7] 主要是一个可视化的比较和合并的工具,目标人群是开发者(当然,我们将要讲到的其它部分也会考虑到最终用户)。这个工具同时支持双向和三向的比较,不仅仅是比较文件,还可以比较目录,以及版本控制的项目。 -“Meld 帮你回顾代码改动,理解补丁,”官网如是说。“它甚至可以告知你如果你不进行合并将会发生什么事情。”该工具使用 GPL v2 协议进行授权。 +“Meld 可以帮你回顾代码改动,理解补丁,”其官网如是说。“它甚至可以告知你如果你不进行合并将会发生什么事情。”该工具使用 GPL v2 协议进行授权。 ### 安装 Meld @@ -28,11 +21,13 @@ Linux 系统可视化的比较与合并工具 Meld 的新手使用教程 sudo apt-get install meld ``` -或者你也可以用系统自带的包管理软件下载这个工具。比如在 Ubuntu 上,你可以用 Ubuntu 软件中心(Ubuntu Software Center),或者用 [Ubuntu Software][8],Ubuntu Software 从 Ubuntu 16.04 版本开始取代了软件中心。 +或者你也可以用系统自带的包管理软件下载这个工具。比如在 Ubuntu 上,你可以用 Ubuntu 软件中心(Ubuntu Software Center),或者用 [Ubuntu 软件][8],它从 Ubuntu 16.04 版本开始取代了 Ubuntu 软件中心。 -当然,Ubuntu 官方仓库里的 Meld 版本很有可能比较陈旧。因此如果你想要用更新的版本,你可以在[这里][9]下载软件包。如果你要用这个方法,你要做的就是解压下载好的软件包,然后运行 “bin” 目录下的 “meld” 程序。 +当然,Ubuntu 官方仓库里的 Meld 版本很有可能比较陈旧。因此如果你想要用更新的版本,你可以在[这里][9]下载软件包。如果你要用这个方法,你要做的就是解压下载好的软件包,然后运行 `bin` 目录下的 `meld` 程序。 -~/Downloads/meld-3.14.2/bin$ **./meld**  +``` +~/Downloads/meld-3.14.2/bin$ ./meld  +``` 以下是 Meld 依赖的软件,仅供参考: @@ -67,9 +62,9 @@ sudo apt-get install meld ![Compare files in Meld](https://www.howtoforge.com/images/how-to-use-visual-diff-and-merge-tools-in-linux-meld-and-kdiff/meld-diff-in-action-3.png) ][12] -两个文件的不同之处在第二行,差别在于 “file2” 文件的第二行多了一个 “3”。你看到的黑色箭头是用来进行合并或修改的操作的。该例中,向右的箭头将会把 “file2” 文件的第二行改成文件 “file1” 中对应行的内容。左向箭头做的事情相反。 +两个文件的不同之处在第二行,差别在于 `file2` 文件的第二行多了一个 `3`。你看到的黑色箭头是用来进行合并或修改的操作的。该例中,向右的箭头将会把 `file2` 文件的第二行改成文件 `file1` 中对应行的内容。左向箭头做的事情相反。 -做完修改后,按下 Ctrl+s 来保存。 +做完修改后,按下 `Ctrl+s` 来保存。 这个简单的例子,让你知道 Meld 的基本用法。让我们看一看稍微复杂一点的比较: @@ -77,13 +72,13 @@ sudo apt-get install meld ![Meld advanced file comparison](https://www.howtoforge.com/images/how-to-use-visual-diff-and-merge-tools-in-linux-meld-and-kdiff/meld-multiple-changes-4.png) ][13] -在讨论这些变化前,这里提一下, Meld GUI 中有几个区域,可以给出文件之间的差异,让概况变得直观。这里特别需要注意窗口的左右两边垂直的栏。比如下面这个截图: +在讨论这些变化前,这里提一下, Meld 的界面中有几个区域,可以给出文件之间的差异,让概况变得直观。这里特别需要注意窗口的左右两边垂直的栏。比如下面这个截图: [ ![Visual Comparison](https://www.howtoforge.com/images/how-to-use-visual-diff-and-merge-tools-in-linux-meld-and-kdiff/meld-multiple-colors-5.png) ][14] -仔细观察,图中的这个栏包含几个不同颜色的区块。这些区块是用来让你对文件之间的差异有个大概的了解。“每一个上色的区块表示一个部分,这个部分可能是插入、删除、修改或者有差别的,取决于区块所用的颜色。”官方文档是这样说的。 +仔细观察,图中的这个栏包含几个不同颜色的区块。这些区块是用来让你对文件之间的差异有个大概的了解。“每一个着色的区块表示一个部分,这个部分可能是插入、删除、修改或者有差别的,取决于区块所用的颜色。”官方文档是这样说的。 现在,让我们回到我们之前讨论的例子中。接下来的截图展示了用 Meld 理解文件的改动是很简单的(以及合并这些改动): @@ -105,19 +100,19 @@ sudo apt-get install meld ![Go to next change in Meld](https://www.howtoforge.com/images/how-to-use-visual-diff-and-merge-tools-in-linux-meld-and-kdiff/meld-go-next-prev-9.png) ][18] -这些是你使用 Meld 时做的一般性的事情:可以用标准的 “Ctrl+f” 组合键在编辑区域内进行查找,按 “F11” 键让软件进入全屏模式,再按 “Ctrl+f” 来刷新(通常在所有要比较的文件改变的时候使用)。 +这些是你使用 Meld 时做的一般性的事情:可以用标准的 `Ctrl+f` 组合键在编辑区域内进行查找,按 `F11` 键让软件进入全屏模式,再按 `Ctrl+r` 来刷新(通常在所有要比较的文件改变的时候使用)。 以下是 Meld 官方网站宣传的重要特性: * 文件和目录的双向及三向比较 * 输入即更新文件的比较 -* 自动合并模式,改动区块的动作让合并更加简单 +* 自动合并模式,按块改动的动作让合并更加简单 * 可视化让比较文件更简单 * 支持 Git,Bazaar,Mercurial,Subversion 等等 -注意还不仅仅只有以上所列的。网站上有个专门的[特性页面][19],里面提到了 Meld 提供的所有特性。这个页面列出的所有特性分为几个部分,以该软件是用来做文件比较,目录比较,版本控制还是处于合并模式下为基础进行划分。 +注意还不仅仅只有以上所列的。网站上有个专门的[特性页面][19],里面提到了 Meld 提供的所有特性。这个页面列出的所有特性分为几个部分,以该软件是用来做文件比较、目录比较、版本控制还是处于合并模式下为基础进行划分。 -和其它软件相似,有些事情 Meld 做不到。官方网站上列出了其中的一部分:“当 Meld 展示文件之间的差异时,它同时显示两个文件,看起来就像在普通的文本编辑器中。它不会添加额外的行,让左右两边文件的特殊改动是同样的行数。没有做这个事情的选项。” +和其它软件相似,有些事情 Meld 做不到。官方网站上列出了其中的一部分:“当 Meld 展示文件之间的差异时,它同时显示两个文件,看起来就像在普通的文本编辑器中。它不会添加额外的行,让左右两边文件的特殊改动处于同样的行数。没有做这个事情的选项。” ### 总结 @@ -129,7 +124,7 @@ via: https://www.howtoforge.com/tutorial/beginners-guide-to-visual-merge-tool-me 作者:[Ansh][a] 译者:[GitFuture](https://github.com/GitFuture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 75bbdc938347cde6194374c72f50afb07a686af1 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 14 Apr 2017 16:50:16 +0800 Subject: [PATCH 05/37] PRF&PUB:20170128 How communities in India support privacy and software freedom.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @geekpi 这篇翻译质量很高! --- ...ia support privacy and software freedom.md | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) rename {translated/tech => published}/20170128 How communities in India support privacy and software freedom.md (65%) diff --git a/translated/tech/20170128 How communities in India support privacy and software freedom.md b/published/20170128 How communities in India support privacy and software freedom.md similarity index 65% rename from translated/tech/20170128 How communities in India support privacy and software freedom.md rename to published/20170128 How communities in India support privacy and software freedom.md index 56cb37cb2a..f5005dc98d 100644 --- a/translated/tech/20170128 How communities in India support privacy and software freedom.md +++ b/published/20170128 How communities in India support privacy and software freedom.md @@ -1,24 +1,25 @@ -印度社区如何支持隐私和软件自由 +印度的社区如何支持隐私和软件自由 ============================================================ ![How communities in India support privacy and software freedom](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/people_remote_teams_world.png?itok=wI-GW8zX "How communities in India support privacy and software freedom") + 图片提供: opensource.com -印度的自由和开源社区,特别是 Mozilla 和 Wikimedia 社区,它们正在引领两个独特的全球性活动,以提高隐私及支持自由软件。 +印度的自由和开源社区,特别是 Mozilla 和 Wikimedia 社区,它们正在引领两个独特的全球性活动,以提高隐私保护及支持自由软件。 [1 月份的隐私月][3]是由印度 Mozilla 社区领导,通过在线和线下活动向群众教育网络隐私。而[ 2 月份的自由月][4]是由[互联网与社会中心][5]领导,教育内容创作者如博主和摄影师就如何在[开放许可证][6]下捐赠内容。 ### 1 月隐私月 -从[去年开始][7]的 Mozilla “1 月隐私月”用来帮助庆祝年度[数据隐私日][8]。在 2016 年,该活动举办了几场涉及[全球 10 个国家 14,339,443 人][9]的线下和线上活动。其中一个核心组织者,[Ankit Gadgil][10]这样说到:“每天分享一个隐私提示,持续一个月 31 天是有可能的。今年,我们共有三个重点领域,首先是我们让这个运动更加开放和全球化。巴西、意大利、捷克共和国的 Mozilla 社区今年正在积极参与,所有的必要文件都是本地化的,所以我们可以针对更多的用户。其次,我们在线下活动中教导用户营销 Firefox 以及 Mozilla 的其他产品,以便用户可以亲身体验使用这些工具来帮助保护他们的隐私。第三点,我们鼓励大家参加线下活动并记录他们的学习,例如,最近在印度古吉拉特邦的一个节目中,他们使用 Mozilla 产品来教授隐私。” +从[去年开始][7]的 Mozilla “1 月隐私月”用来帮助庆祝年度[数据隐私日(Data Privacy Day)][8]。在 2016 年,该活动举办了几场涉及到[全球 10 个国家 14,339,443 人][9]的线下和线上活动。其中一个核心组织者,[Ankit Gadgil][10] 这样说到:“每天分享一个隐私提示,持续一个月就能分享 31 天。”今年,我们共有三个重点领域,首先是我们让这个运动更加开放和全球化。巴西、意大利、捷克共和国的 Mozilla 社区今年正在积极参与,所有必要的文档都是本地化的,所以我们可以针对更多的用户。其次,我们在线下活动中教导用户推广 Firefox 以及 Mozilla 的其他产品,以便用户可以亲身体验使用这些工具来帮助保护他们的隐私。第三点,我们鼓励大家参加线下活动并把他们的学习写到博客里面去,例如,最近在印度古吉拉特邦的一个节目中,他们使用 Mozilla 产品来教授隐私方面的知识。” 今年的活动继续有线下和线上活动。关注 #PrivacyAware 参加。 -### 安全提示 +#### 安全提示 -像 Firefox 这样的 Mozilla 产品具有安全性设置-同时还有[内建][11]还有附加的对残疾人完全[可用][12]的库-这有助于保护用户的隐私和安全性,这些都是协同构建的并且是开源的。 +像 Firefox 这样的 Mozilla 产品具有安全性设置-有[内置的][11]还有对残疾人完全[可用][12]的附件库-这有助于保护用户的隐私和安全性,这些都是协同构建的并且是开源的。 -[Chrome][14] 和[ Opera][15] 中的 [HTTPS Everywhere][13] 可用于加密用户通信,使外部网站无法查看用户信息。该项目由 [Tor Project][16]以及[电子前沿基金会][17]合作建成。 +[Chrome][14] 和[ Opera][15] 中的 [HTTPS Everywhere][13] 插件可用于加密用户通信,使外部网站无法查看用户信息。该项目由 [Tor Project][16] 以及[电子前沿基金会][17]合作建成。 ### 2 月自由月 @@ -27,15 +28,15 @@ ** 参加规则:** * 你在二月份制作或出版的作品必须获得[自由许可证][1]许可。 -* 内容类型包括博客帖子、其他文字和图像。 +* 内容类型包括博客文章、其他文字和图像。 -多媒体,基于文本的内容,艺术和设计等创意作品可以通过多个[知识共享许可证][20](CC)进行许可,其他类型的文档可以根据[ GNU 免费文档许可][21](GFDL)许可。Wikipedia 上可以找到很好的例子,其内容根据 CC 和 GFDL 许可证获得许可,允许人们使用、分享、混合和分发衍生用于商业上和非商业性的作品。此外,还有允许开发人员共享他们的软件和软件相关文档的[自由软件许可证][22]。 +多媒体,基于文本的内容,艺术和设计等创意作品可以通过多个[知识共享许可证][20](CC)进行许可,其他类型的文档可以根据 [GNU 免费文档许可][21](GFDL)许可。Wikipedia 上可以找到很好的例子,其内容根据 CC 和 GFDL 许可证获得许可,允许人们使用、分享、混合和分发衍生用于商业上和非商业性的作品。此外,还有允许开发人员共享他们的软件和软件相关文档的[自由软件许可证][22]。 -------------------------------------------------------------------------------- 作者简介: -Subhashish Panigrahi - Subhashish Panigrahi(@shhapa)是 Mozilla 参与团队的亚洲社区催化师,并从 Wikimedia 基金会印度计划的早期扮演了互联网及社会知识获取中心项目官的角色,另外他是一名印度教育者, +Subhashish Panigrahi(@shhapa)是 Mozilla 参与团队的亚洲社区催化师,并在 Wikimedia 基金会印度计划的早期扮演了互联网及社会知识获取中心项目官的角色,另外他是一名印度教育工作者, -------------------------------------------------------------------------------- @@ -43,7 +44,7 @@ via: https://opensource.com/article/17/1/how-communities-india-support-privacy-s 作者:[Subhashish Panigrahi][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 1728b0cfdb0cfecd64d36326a1a18df252d0f90d Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Fri, 14 Apr 2017 17:07:27 +0800 Subject: [PATCH 06/37] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对中 --- ...0403 Yes Python is Slow and I Dont Care.md | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md index c32d2ffb51..cd5587f971 100644 --- a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md +++ b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md @@ -5,75 +5,75 @@ python 是慢,但是爷就喜欢它 ![](https://cdn-images-1.medium.com/max/800/0*pWAgROZ2JbYzlDgj.jpg) - 我从关于Python中的asyncio这个标准库的讨论中休息一会,这次讨论是要谈论我最近正在思考的一些东西:Python的速度。相比那些不了解Python的人,我是一个Python的粉丝,而且我在我能想到的所有地方都积极地使用Python。人们对Python最大的抱怨之一就是它的速度比较慢,有些人甚至拒绝尝试使用Python,因为它比其他语言更慢的速度。这里我对于为什么你应该尝试使用Python的一些想法,尽管它是有点慢。 +我从关于 Python 中的 asyncio 这个标准库的讨论中休息一会,谈谈我最近正在思考的一些东西:Python 的速度。对不了解我的人说明一下,我是一个 Python 的粉丝,而且我在我能想到的所有地方都积极地使用 Python。人们对 Python 最大的抱怨之一就是它的速度比较慢,有些人甚至拒绝尝试使用 Python,因为它比其他语言速度慢。这里说说为什么我认为应该尝试使用 Python,尽管它是有点慢。 ### 速度不再重要 -过去的情形是,程序需要花费很长的时间来运行,CPU比较贵,内存更加贵。程序的运行时间是一个很重要的指标。计算机非常的昂贵,计算机运行所需要的电也是相当贵的。对这些资源进行优化是因为一个永恒的商业法则: +过去的情形是,程序需要花费很长的时间来运行,CPU 比较贵,内存也很贵。程序的运行时间是一个很重要的指标。计算机非常的昂贵,计算机运行所需要的电也是相当贵的。对这些资源进行优化是因为一个永恒的商业法则: -> 优化你最贵的资源 +> 优化你最贵的资源Optimize your most expensive resource。 在过去,最贵的资源是计算机的运行时间。这就是导致计算机科学致力于研究不同算法的效率的原因。然而,这已经不再是正确的,因为现在硅芯片很便宜,确实很便宜。运行时间不再是你最贵的资源。公司最贵的资源现在是它的员工的时间。或者换句话说,就是你。把事情做完比快速地做事更加重要。实际上,这是相当的重要,我将把它再次放在这里,仿佛它是一个引用一样(对于那些只是粗略浏览的人): -> 把事情做完比快速地做事更加重要。 +> 把事情做完比快速地做事更加重要It’s more important to get stuff done than to make it go fast。 -你可能会说:"我的公司在意速度,我开发一个web应用程序,那么所有的响应时间必须少于x毫秒。"或者,"我们失去了客户,因为他们认为我们的app运行太慢了。"我并不是想说速度一点也不重要,我只是想说速度不再是最重要的东西;它不再是你最贵的资源。 +你可能会说:“我的公司在意速度,我开发一个 web 应用程序,那么所有的响应时间必须少于 x 毫秒。”或者,“我们失去了客户,因为他们认为我们的 app 运行太慢了。”我并不是想说速度一点也不重要,我只是想说速度不再是最重要的东西;它不再是你最贵的资源。 ![](https://cdn-images-1.medium.com/max/800/0*Z6j9zMua_w-T25TC.jpg) ### 速度是唯一重要的东西 -当你在编程的背景下说 _速度_ 时,你通常意味着性能,也就是CPU周期。当你的CEO在编程的背景下说 _速度_ 时,他指的是业务速度,最重要的指标是产品上市的时间。基本上,你的产品/web程序是多么的快并不重要。它是用什么语言写的也不重要。甚至它需要花费多少钱也不重要。在一天结束时,让你的公司存活下来或者死去的唯一事物就是产品上市时间。我不只是说创业公司的想法--你开始赚钱需要花费多久,更多的是"从想法到客户手中"的时间期限。企业能够存活下来的唯一方法就是比你的竞争对手更快地创新。如果在你将立产品上市之前,你的竞争对手已经提前上市了,那么你想出了多少好的主意也将不再重要。你不得不成为第一个上市的,或者至少能跟上。你但你放慢了脚步,你就输了。 +当你在编程的背景下说 _速度_ 时,你通常意味着性能,也就是 CPU 周期。当你的 CEO 在编程的背景下说 _速度_ 时,他指的是业务速度,最重要的指标是产品上市的时间。基本上,你的产品/web 程序是多么的快并不重要。它是用什么语言写的也不重要。甚至它需要花费多少钱也不重要。在一天结束时,让你的公司存活下来或者死去的唯一事物就是产品上市时间。我不只是说创业公司的想法 -- 你开始赚钱需要花费多久,更多的是“从想法到客户手中”的时间期限。企业能够存活下来的唯一方法就是比你的竞争对手更快地创新。如果在你的产品上市之前,你的竞争对手已经提前上市了,那么你想出了多少好的主意也将不再重要。你必须第一个上市,或者至少能跟上。一但你放慢了脚步,你就输了。 -> 企业能够存活下来的唯一方法就是比你的竞争对手更快地创新。 +> 企业能够存活下来的唯一方法就是比你的竞争对手更快地创新The only way to survive in business is to innovate faster than your competitors。 -### 一个微服务的案例 +#### 一个微服务的案例 -像Amazon、Google和Netflix这样的公司明白快速前进的重要性。他们创建了一个业务系统,他们可以使用这个系统迅速地前进和快速的创新。微服务是针对他们的问题的解决方案。这篇文章与你是否应该使用微服务没有关系,但是至少得接受Amazon和Google认为他们应该使用微服务。 +像 Amazon、Google 和 Netflix 这样的公司明白快速前进的重要性。他们创建了一个业务系统,可以使用这个系统迅速地前进和快速的创新。微服务是针对他们的问题的解决方案。这篇文章不谈你是否应该使用微服务,但是至少要接受 Amazon 和 Google 认为他们应该使用微服务。 ![](https://cdn-images-1.medium.com/max/600/0*MBM9zatYv_Lzr3QN.jpg) - 微服务本来就很慢。微服务的一个恰当的概念是用网络调用来打破一个边界。这意味着你正在采取一个函数调用(几个cpu周期)并把这转变为一个网络调用。没有什么比这更影响性能了。和CPU想比较,网络调用真的很慢。但是这些大公司仍然选择使用微服务。我所知道的架构里面没有任何一个比微服务还要慢。微服务最大的弊端就是它的性能,但是最大的长处就是上市的时间。通过团结较小的项目和代码库建立团队,一个公司能够以更快的速度进行迭代和创新。这恰恰表明了,非常大的公司也很在意上市时间,而不仅仅只是只有创业公司。 +微服务本来就很慢。微服务的主要概念是用网络调用来打破边界。这意味着你正在使用一个函数调用(几个 cpu 周期)并将它转变为一个网络调用。没有什么比这更影响性能了。和 CPU 相比较,网络调用真的很慢。但是这些大公司仍然选择使用微服务。我所知道的架构里面没有比微服务还要慢的了。微服务最大的弊端就是它的性能,但是最大的长处就是上市的时间。通过在较小的项目和代码库上建立团队,一个公司能够以更快的速度进行迭代和创新。这恰恰表明了,非常大的公司也很在意上市时间,而不仅仅只是只有创业公司。 -### CPU不是你的瓶颈 +#### CPU不是你的瓶颈 ![](https://cdn-images-1.medium.com/max/800/0*s1RKhkRIBMEYji_w.jpg) - 如果你在写一个网络应用程序,如web服务器,很有可能的情况会是,CPU时间并不是你的程序的瓶颈。当你的web服务器处理一个请求时,可能会进行几次网络调用,例如数据库,或者像Redis这样的缓存服务器。虽然这些服务本身可能比较快速,但是对它们的网络调用却很慢。[有一篇很好的关于特定操作的速度差异的博客文章][1]。在这篇文章里,作者把CPU周期时间缩放到更容易理解的人类时间。如果一个单独的周期等同于1秒,那么一个从California到New York的网络调用将相当于4年。那就说明了网络调用是多少的慢。对于一些粗略估计,我们可以假设在同一数据中心内的普通网络调用大约需要3ms。这相当于我们“人类比例”3个月。现在假设你的程序是高CPU密集型,这需要100000个CPU周期来对单一调用进行响应。这相当于刚刚超过1天。现在让我们假设你使用的是一种要慢5倍的语言,这将需要大约5天。很好,将那与我们3个月的网络调用时间相比,4天的差异就显得并不是很重要了。如果有人为了一个包裹不得不至少等待3个月,我不认为额外的4天对他们来说真的很重要。 + 如果你在写一个网络应用程序,如 web 服务器,很有可能的情况会是,CPU 时间并不是你的程序的瓶颈。当你的 web 服务器处理一个请求时,可能会进行几次网络调用,例如到数据库,或者像 Redis 这样的缓存服务器。虽然这些服务本身可能比较快速,但是对它们的网络调用却很慢。[有一篇很好的关于特定操作的速度差异的博客文章][1]。在这篇文章里,作者把 CPU 周期时间缩放到更容易理解的人类时间。如果一个单独的周期等同于 1 秒,那么一个从 California 到 New York 的网络调用将相当于 4 年。那就说明了网络调用是多少的慢。按一些粗略估计,我们可以假设在同一数据中心内的普通网络调用大约需要 3 ms。这相当于我们“人类比例” 3 个月。现在假设你的程序是高 CPU 密集型,这需要 100000 个 CPU 周期来对单一调用进行响应。这相当于刚刚超过 1 天。现在让我们假设你使用的是一种要慢 5 倍的语言,这将需要大约 5 天。很好,将那与我们 3 个月的网络调用时间相比,4 天的差异就显得并不是很重要了。如果有人为了一个包裹不得不至少等待 3 个月,我不认为额外的 4 天对他们来说真的很重要。 -上面所说的终极意思是,尽管Python速度慢,但是这并不重要。语言的速度(或者CPU时间)几乎从来不是问题。实际上谷歌曾经就这一概念做过一个研究,[并且他们发表过一篇关于这的论文][2]。那篇论文论述了设计高吞吐量的系统。在结论里,他们说到: +上面所说的终极意思是,尽管 Python 速度慢,但是这并不重要。语言的速度(或者 CPU 时间)几乎从来不是问题。实际上谷歌曾经就这一概念做过一个研究,[并且他们就此发表过一篇论文][2]。那篇论文论述了设计高吞吐量的系统。在结论里,他们说到: -> 在高吞吐量的环境中使用解释性语言似乎是矛盾的,但是我们已经发现CPU时间几乎不是限制因素;语言的表达性是指,大多数程序是源程序,同时花费它们的大多数时间在I/O读写和本机运行时代码。而且,解释性语言无论是在语言层面的轻松实验还是在允许我们在很多机器上探索分布计算的方法都是很有帮助的, +> 在高吞吐量的环境中使用解释性语言似乎是矛盾的,但是我们已经发现 CPU 时间几乎不是限制因素;语言的表达性是指,大多数程序是源程序,同时花费它们的大多数时间在 I/O 读写和本机运行时代码。而且,解释性语言无论是在语言层面的轻松实验还是在允许我们在很多机器上探索分布计算的方法都是很有帮助的, 再次强调: -> CPU时间几乎不是限制因素。 +> CPU 时间几乎不是限制因素the CPU time is rarely the limiting factor。 -### 如果CPU时间是一个问题怎么办? +### 如果 CPU 时间是一个问题怎么办? -你可能会说,"前面说的情况真是太好了,但是我们确实有过一些问题,这些问题中CPU成为了我们的瓶颈,并造成了我们的web应用的速度十分缓慢",或者"在服务器上X语言比Y语言需要需要更少的硬件资源来运行。"这些都可能是对的。关于web服务器有这样的美妙的事情:你可以几乎无限地负载均衡它们。换句话说,可以在web服务器上投入更多的硬件。当然,Python可能会比其他语言要求更好的硬件资源,比如c语言。只是把硬件投入在CPU问题上。相比于你的时间,硬件就显得非常的便宜了。如果你在一年内节省了两周的生产力时间,那将远远多于所增加的硬件开销的回报。 +你可能会说,“前面说的情况真是太好了,但是我们确实有过一些问题,这些问题中 CPU 成为了我们的瓶颈,并造成了我们的 web 应用的速度十分缓慢”,或者“在服务器上 X 语言比 Y 语言需要更少的硬件资源来运行。”这些都可能是对的。关于 web 服务器有这样的美妙的事情:你可以几乎无限地负载均衡它们。换句话说,可以在 web 服务器上投入更多的硬件。当然,Python 可能会比其他语言要求更好的硬件资源,比如 c 语言。只是把硬件投入在 CPU 问题上。相比于你的时间,硬件就显得非常的便宜了。如果你在一年内节省了两周的生产力时间,那将远远多于所增加的硬件开销的回报。 * * * ![](https://cdn-images-1.medium.com/max/1000/0*mJFOcWsdEQq98gkF.jpg) -### 那么,Python是更快吗? +### 那么,Python 是更快吗? -这一次我一直在谈论最重要的是开发时间。所以问题依然存在:当就开发时间而言,Python要比其他语言更快吗?按常规惯例来看,我、[google][3][还有][4][其他][5][几个人][6]可以告诉你Python是多么的[高效][7]。它为你抽象出很多东西,帮助你关注那些你真正应该编写代码的地方,而不会被困在琐碎事情的杂草里,比如你是否应该使用一个向量或者一个数组。但你可能不喜欢别人的对Python说的些话,所以让我们来看一些更多的经验数据。 +这一次我一直在谈论最重要的是开发时间。所以问题依然存在:当就开发时间而言,Python 要比其他语言更快吗?按常规惯例来看,我、[google][3] [还有][4][其他][5][几个人][6]可以告诉你 Python 是多么的[高效][7]。它为你抽象出很多东西,帮助你关注那些你真正应该编写代码的地方,而不会被困在琐碎事情的杂草里,比如你是否应该使用一个向量或者一个数组。但你可能不喜欢只是听别人说的这些话,所以让我们来看一些更多的经验数据。 -在大多数情况下,关于python是否是更高效语言的争论可以归结为脚本语言(或动态语言)与静态类型语言两者的争论。我认为人们普遍接受的是静态类型语言的生产力较低,但是,[这里有一篇解释了为什么是这样的优秀的论文][8]。就Python而言,这里是一项研究中的给出的一个很好的总结][9],这项研究调查了用不同的语言编写对字符串处理的代码所需要花费的时间。 +在大多数情况下,关于 python 是否是更高效语言的争论可以归结为脚本语言(或动态语言)与静态类型语言两者的争论。我认为人们普遍接受的是静态类型语言的生产力较低,但是,[这有一篇优秀的论文][8]解释了为什么不是这样。就 Python 而言,这里有一项[研究][9],它调查了不同语言编写字符串处理的代码所需要花费的时间,供参考。 ![](https://cdn-images-1.medium.com/max/800/1*cw7Oq54ZflGZhlFglDka4Q.png) -在上述研究中,Python的效率比Java高出2倍。有一些其他研究也显示相似的东西。 Rosetta Code对编程语言的差异进行了[深入的研究][10]。在论文中,他们把python与其他脚本语言/解释性语言相比较,得出结论: +在上述研究中,Python 的效率比 Java 高出 2 倍。有一些其他研究也显示相似的东西。 Rosetta Code 对编程语言的差异进行了[深入的研究][10]。在论文中,他们把 python 与其他脚本语言/解释性语言相比较,得出结论: -> Python侧重于更简洁,甚至反对函数式语言(平均要短1.2到1.6倍) -> +> Python 更简洁,即使与函数式语言相比较(平均要短 1.2 到 1.6 倍) +>   -普遍的趋势似乎是Python中的代码行总是更少。代码行听起来可能像一个可怕的指标,但是包括上面已经提到到的两项研究在内的[多项研究][11]表明每种语言中每行代码所需要花费的时间大约是一样的。因此,通过限制代码行数提高生产效率。甚至codinghorror(一名C#程序员)他本人[写了一篇关于Python是如何更有效率的文章][12]。 +普遍的趋势似乎是 Python 中的代码行总是更少。代码行听起来可能像一个可怕的指标,但是包括上面已经提到的两项研究在内的[多项研究][11]表明,每种语言中每行代码所需要花费的时间大约是一样的。因此,限制代码行数就可以提高生产效率。甚至 codinghorror(一名 C# 程序员)本人[写了一篇关于 Python 是如何更有效率的文章][12]。 -我认为说Python比其他的很多语言更加的有效率是公正的。这主要是由于 Python 有大量的自带以及第三方库。[这里是一篇讨论Python和其他语言间的差异的简单的文章][13]。如果你不知道为何Python是如此的小巧和高效,我邀请你借此机会学习一点python,自己多实践。这儿是你的第一个程序: +我认为说 Python 比其他的很多语言更加的有效率是公正的。这主要是由于 Python 有大量的自带以及第三方库。[这里是一篇讨论 Python 和其他语言间的差异的简单的文章][13]。如果你不知道为何 Python 是如此的小巧和高效,我邀请你借此机会学习一点 python,自己多实践。这儿是你的第一个程序: _import __hello___ @@ -83,6 +83,7 @@ python 是慢,但是爷就喜欢它 -------------------------------------------------------------------------------- + via: https://hackernoon.com/yes-python-is-slow-and-i-dont-care-13763980b5a1 作者:[Nick Humrich ][a] From f7bf220dbc56a7a705dc596aff3797fcaf3069a3 Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Fri, 14 Apr 2017 17:13:44 +0800 Subject: [PATCH 07/37] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对中 --- translated/tech/20170406 Anbox - Android in a Box.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translated/tech/20170406 Anbox - Android in a Box.md b/translated/tech/20170406 Anbox - Android in a Box.md index a206f29624..05ac1eeb9e 100644 --- a/translated/tech/20170406 Anbox - Android in a Box.md +++ b/translated/tech/20170406 Anbox - Android in a Box.md @@ -167,7 +167,7 @@ via: https://github.com/anbox/anbox/blob/master/README.md 作者:[ Anbox][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[jasminepeng](https://github.com/jasminepeng) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 9b6d127691f1a9f41bd838d1057b690361c9bb7b Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Fri, 14 Apr 2017 17:37:16 +0800 Subject: [PATCH 08/37] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对完毕 谢谢@geekpi --- .../tech/20170406 Anbox - Android in a Box.md | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/translated/tech/20170406 Anbox - Android in a Box.md b/translated/tech/20170406 Anbox - Android in a Box.md index 05ac1eeb9e..fac422a9ac 100644 --- a/translated/tech/20170406 Anbox - Android in a Box.md +++ b/translated/tech/20170406 Anbox - Android in a Box.md @@ -1,33 +1,33 @@ # Anbox -Anbox 是一个基于容器的方式来在像 Ubuntu 这样的常规的 GNU Linux 系统上启动一个完整的 Android 系统。 +Anbox 是一个基于容器的方式,在像 Ubuntu 这样的常规的 GNU Linux 系统上启动一个完整的 Android 系统。 ## 概述 -Anbox 使用 Linux 命名空间(user、pid、uts、net、mount、ipc)来在容器中运行完整的 Android 系统并提供任何基于 GNU Linux 平台的 Android 程序。 +Anbox 使用 Linux 命名空间(user、pid、uts、net、mount、ipc)来在容器中运行完整的 Android 系统,并提供任何基于 GNU Linux 平台的 Android 程序。 -容器内的 Android 无法直接访问任何硬件。所有硬件访问都通过主机上的 anbox 守护进程进行。我们重用基于QEMU的模拟器实现的 Android 中的 GL、ES 加速渲染。容器内的 Android 系统使用不同的管道与主机系统通信并通过它发送所有硬件访问命令。 +容器内的 Android 无法直接访问任何硬件。所有硬件访问都通过主机上的 anbox 守护进程进行。我们重用基于 QEMU 的模拟器实现的 Android 中的 GL、ES 加速渲染。容器内的 Android 系统使用不同的管道与主机系统通信,并通过它发送所有硬件访问命令。 有关更多详细信息,请参考下文档: * [Android 硬件 OpenGL ES 仿真设计概述](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/android-emugl/DESIGN) * [Android QEMU 快速管道](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMU-PIPE.TXT) - * [Android 的 "qemud" 复用守护进程](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD.TXT) + * [Android 的 “qemud” 复用守护进程](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD.TXT) * [Android qemud 服务](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD-SERVICES.TXT) -Anbox 目前适合桌面使用,但也可使用移动操作系统,如 Ubuntu Touch、Sailfish OS 或 Lune OS。然而,由于目前 Android 程序映射针对桌面环境,因此这还需要额外的工作来支持其他的用户界面。 +Anbox 目前适合桌面使用,但也可使用移动操作系统,如 Ubuntu Touch、Sailfish OS 或 Lune OS。然而,由于 Android 程序映射目前只针对桌面环境,因此还需要额外的工作来支持其他的用户界面。 -Android 运行时环境带有一个基于[ Android 开源项目](https://source.android.com/)镜像的最小自定义 Android 系统。所使用的镜像目前基于 Android 7.1.1 +Android 运行时环境带有一个基于[ Android 开源项目](https://source.android.com/)镜像的最小自定义 Android 系统。所使用的镜像目前基于 Android 7.1.1。 ## 安装 -安装过程目前由几个需要添加其他组件到系统中的步骤组成。包括: +目前,安装过程包括一些添加额外组件到系统的步骤。包括: -  * 没有分发版内核同时启用的 binder 和 ashmen 原始内核模块 -  * 使用 udev 规则为 /dev/binder 和 /dev/ashmem 设置正确权限 -  * 能够启动 Anbox 会话管理器作为用户会话的一个启动任务 +  * 没有分发版内核同时启用的 binder 和 ashmen 原始内核模块。 +  * 使用 udev 规则为 /dev/binder 和 /dev/ashmem 设置正确权限。 +  * 能够启动 Anbox 会话管理器作为用户会话的一个启动任务。 -为了使这个过程尽可能简单,我们做了一个简单的步骤(见 https://snapcraft.io),称为 “anbox-installer”。这个安装程序会执行所有必要的步骤。你可以在所有支持 snap 的系统运行下面的命令安装它。 +为了使这个过程尽可能简单,我们将必要的步骤绑定在一个 snap(见 https://snapcraft.io) 中,称为“anbox-installer”。这个安装程序会执行所有必要的步骤。你可以在所有支持 snap 的系统运行下面的命令安装它。 ``` $ snap install --classic anbox-installer @@ -39,7 +39,7 @@ $ snap install --classic anbox-installer $ wget https://raw.githubusercontent.com/anbox/anbox-installer/master/installer.sh -O anbox-installer ``` -请注意,我们还不支持除本文列出的其他 Linux 发行版。请查看下面的章节了解支持的发行版。 +请注意,我们还不支持除所有 Linux 发行版。请查看下面的章节了解支持的发行版。 运行下面的命令进行安装。 @@ -47,11 +47,11 @@ $ wget https://raw.githubusercontent.com/anbox/anbox-installer/master/installer. $ anbox-installer ``` -本篇会引导你完成安装过程。 +它会引导你完成安装过程。 -**注意:** Anbox 目前处于** pre-alpha 的开发状态**。不要指望它具有生产环境你需要的所有功能。你肯定会遇到错误和崩溃。如果你遇到了,请不要犹豫并报告他们! +**注意:** Anbox 目前处于** pre-alpha 开发状态**。不要指望它具有生产环境你需要的所有功能。你肯定会遇到错误和崩溃。如果你遇到了,请不要犹豫并报告它们! -**注意:** Anbox snap 目前 **完全没有约束**,这是因为它只能从前沿频道获取。正确的约束是我们想要在未来实现的,但由于 Anbox 的性质和复杂性,这不是一个简单的任务。 +**注意:** Anbox snap 目前 **完全没有约束**,因此它只能从边缘渠道获取。正确的约束是我们想要在未来实现的,但由于 Anbox 的性质和复杂性,这不是一个简单的任务。 ## 已支持的 Linux 发行版 @@ -69,7 +69,7 @@ $ anbox-installer ## 从源码构建 -要构建 Anbox 运行时不需要特别了解什么,我们使用 cmake 作为构建系统。你系统中只需要一点构建依赖: +要构建 Anbox 运行时不需要特别了解什么,我们使用 cmake 作为构建系统。你的主机系统中应已有下面这些构建依赖: * libdbus * google-mock @@ -112,14 +112,12 @@ $ cmake .. $ make ``` -一个简单的 +一个简单的命令会将必要的二进制安装到你的系统中,如下。 ``` $ make install ``` -会将必要的二进制安装到你的系统中。 - 如果你想要构建 anbox snap,你可以按照下面的步骤: ``` @@ -128,7 +126,7 @@ $ cp /path/to/android.img android-images/android.img $ snapcraft ``` -T结果是会有一个 .snap 文件,你可以在支持 snap 的系统上安装。 +结果会有一个 .snap 文件,你可以在支持 snap 的系统上安装。 ``` $ snap install --dangerous --devmode anbox_1_amd64.snap @@ -136,7 +134,7 @@ $ snap install --dangerous --devmode anbox_1_amd64.snap ## 运行 Anbox -要从本地构建运行 Anbox ,你需要了解更多一点。请参考["运行时步骤"](docs/runtime-setup.md)文档。 +要从本地构建运行 Anbox ,你需要了解更多一点。请参考[“运行时步骤”](docs/runtime-setup.md)文档。 ## 文档 @@ -157,7 +155,7 @@ $ snap install --dangerous --devmode anbox_1_amd64.snap ## 版权与许可 -Anbox 重用了像 Android QEMU 模拟器这样的其他项目。这些项目可在外部、带有许可声明的子目录中得到。 +Anbox 重用了像 Android QEMU 模拟器这样的其他项目的代码。这些项目可在外部/带有许可声明的子目录中得到。 anbox 源码本身,如果没有在相关源码中声明其他的许可,默认是 GPLv3 许可。 From cdb8f474d95d80db1b11a74fc1814af2a6642098 Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Fri, 14 Apr 2017 17:39:04 +0800 Subject: [PATCH 09/37] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E5=AE=8C=E6=AF=95=20@z?= =?UTF-8?q?housiyu325?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 但是翻译没有完成,还请全部完成后再提交哦。谢谢。 --- translated/tech/20170403 Yes Python is Slow and I Dont Care.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md index cd5587f971..95f83385c3 100644 --- a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md +++ b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md @@ -87,7 +87,7 @@ python 是慢,但是爷就喜欢它 via: https://hackernoon.com/yes-python-is-slow-and-i-dont-care-13763980b5a1 作者:[Nick Humrich ][a] -译者:[译者ID](https://github.com/译者ID) +译者:[zhousiyu325](https://github.com/zhousiyu325) 校对:[jasminepeng](https://github.com/jasminepeng) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From ec4d4836f39b016defdeb0c36fb0b5794b8fb228 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 14 Apr 2017 17:40:20 +0800 Subject: [PATCH 10/37] PRF:20170217 Understanding the difference between sudo and su.md @zhb127 --- ...ding the difference between sudo and su.md | 91 ++++++++----------- 1 file changed, 36 insertions(+), 55 deletions(-) diff --git a/translated/tech/20170217 Understanding the difference between sudo and su.md b/translated/tech/20170217 Understanding the difference between sudo and su.md index 5fc1672b00..b4bdb24757 100644 --- a/translated/tech/20170217 Understanding the difference between sudo and su.md +++ b/translated/tech/20170217 Understanding the difference between sudo and su.md @@ -1,38 +1,25 @@ -理解 sudo 与 su 之间的区别 +深入理解 sudo 与 su 之间的区别 ============================================================ -### 本文导航 - -1. [Linux su 命令][7] - 1. [su -][1] - 2. [su -c][2] -2. [Sudo vs Su][8] -2. [Sudo vs Su][8] - 1. [关于密码][3] - 2. [默认行为][4] - 3. [日志记录][5] - 4. [灵活性][6] -3. [Sudo su][9] - -在[早前的一篇文章][11]中,我们深入讨论了 `sudo` 命令的相关内容。同时,在该文章的末尾有提到相关的命令 `su` 的部分内容。本文,我们将详细讨论关于 su 命令与 sudo 命令之间的区别。 +在[早前的一篇文章][11]中,我们深入讨论了 `sudo` 命令的相关内容。同时,在该文章的末尾有提到相关的命令 `su` 的部分内容。本文,我们将详细讨论关于 `su` 命令与 `sudo` 命令之间的区别。 在开始之前有必要说明一下,文中所涉及到的示例教程都已经在 Ubuntu 14.04 LTS 上测试通过。 ### Linux su 命令 -su 命令的主要作用是让你可以在已登录的会话中切换到另外一个用户。换句话说,这个工具可以让你在不登出当前用户的情况下登录另外一个用户(以该用户的身份)。 +`su` 命令的主要作用是让你可以在已登录的会话中切换到另外一个用户。换句话说,这个工具可以让你在不登出当前用户的情况下登录为另外一个用户。 -su 命令经常被用于切换到超级用户或 root 用户(因为在命令行下工作,经常需要 root 权限),但是 - 正如前面所提到的 - su 命令也可以用于切换到任意非 root 用户。 +`su` 命令经常被用于切换到超级用户或 root 用户(因为在命令行下工作,经常需要 root 权限),但是 - 正如前面所提到的 - su 命令也可以用于切换到任意非 root 用户。 -如何使用 su 命令切换到 root 用户,如下: +如何使用 `su` 命令切换到 root 用户,如下: [ ![不带命令行参数的 su 命令](https://www.howtoforge.com/images/sudo-vs-su/su-command.png) ][12] -如上,su 命令要求输入的密码是 root 用户密码。所以,一般 su 命令需要输入目标用户的密码。在输入正确的密码之后,su 命令会在终端的当前会话中打开一个子会话。 +如上,`su` 命令要求输入的密码是 root 用户的密码。所以,一般 `su` 命令需要输入目标用户的密码。在输入正确的密码之后,`su` 命令会在终端的当前会话中打开一个子会话。 -### su - +#### su - 还有一种方法可以切换到 root 用户:运行 `su -` 命令,如下: @@ -40,41 +27,36 @@ su 命令经常被用于切换到超级用户或 root 用户(因为在命令 ![su - 命令](https://www.howtoforge.com/images/sudo-vs-su/su-hyphen-command.png) ][13] -那么,`su` 命令与 `su -` 命令之间有什么区别呢?前者在切换到 root 用户之后仍然保持旧的或原始用户的环境,而后者则是创建一个新的环境(由 root 用户 ~/.bashrc 文件所设置的环境),相当于使用 root 用户正常登录(从登录屏幕显示登录)。 +那么,`su` 命令与 `su -` 命令之间有什么区别呢?前者在切换到 root 用户之后仍然保持旧的(或者说原始用户的)环境,而后者则是创建一个新的环境(由 root 用户 `~/.bashrc` 文件所设置的环境),相当于使用 root 用户正常登录(从登录屏幕登录)。 `su` 命令手册页很清楚地说明了这一点: -``` -可选参数 `-` 可提供的环境为用户在直接登录时的环境。 -``` +> 可选参数 `-` 可提供的环境为用户在直接登录时的环境。 -因此,你会觉得使用 `su -` 登录更有意义。但是,同时存在 `su` 命令,那么大家可能会想知道它在什么时候用到。以下内容摘自[ArchLinux wiki website][14] - 关于 `su` 命令的好处和坏处: +因此,你会觉得使用 `su -` 登录更有意义。但是, `su` 命令也是有用的,那么大家可能会想知道它在什么时候用到。以下内容摘自 [ArchLinux wiki 网站][14] - 关于 `su` 命令的好处和坏处: -* 有的时候,对于系统管理员来讲,使用其他普通用户的 Shell 账户而不是自己的 Shell 账户更会好一些。尤其是在处理用户问题时,最有效的方法就是是:登录目标用户以便重现以及调试问题。 +* 有的时候,对于系统管理员(root)来讲,使用其他普通用户的 Shell 账户而不是自己的 root Shell 账户更会好一些。尤其是在处理用户问题时,最有效的方法就是是:登录目标用户以便重现以及调试问题。 +* 然而,在多数情况下,当从普通用户切换到 root 用户进行操作时,如果还使用普通用户的环境变量的话,那是不可取甚至是危险的操作。因为是在无意间切换使用普通用户的环境,所以当使用 root 用户进行程序安装或系统更改时,会产生与正常使用 root 用户进行操作时不相符的结果。例如,以普通用户安装程序会给普通用户意外损坏系统或获取对某些数据的未授权访问的能力。 -* 然而,在多数情况下,当从普通用户切换到 root 用户进行操作时,如果还使用普通用户的环境变量的话,那是不可取甚至是危险的操作。因为是在无意间切换使用普通用户的环境,所以当使用 root 用户进行程序安装或系统更改时,会产生与正常使用 root 用户进行操作时不相符的结果。例如,可以给普通用户安装电源意外损坏系统的程序或获取对某些数据的未授权访问的程序。 +注意:如果你想在 `su -` 命令的 `-` 后面传递更多的参数,那么你必须使用 `su -l` 而不是 `su -`。以下是 `-` 和 `-l` 命令行选项的说明: -注意:如果你想在 `su -` 命令后面传递更多的参数,那么你必须使用 `su -l` 来实现。以下是 `-` 和 `-l` 命令行选项的说明: +> `-`, `-l`, `--login` -``` --, -l, --login -提供相当于用户在直接登录时所期望的环境。 +> 提供相当于用户在直接登录时所期望的环境。 -当使用 - 时,必须放在 su 命令的最后一个选项。其他选项(-l 和 --login)无此限制。 -``` +> 当使用 - 时,必须放在 `su` 命令的最后一个选项。其他选项(`-l` 和 `--login`)无此限制。 -### su -c +#### su -c 还有一个值得一提的 `su` 命令行选项为:`-c`。该选项允许你提供在切换到目标用户之后要运行的命令。 `su` 命令手册页是这样说明: -``` --c, --command COMMAND -使用 -c 选项指定由 Shell 调用的命令。 +> `-c`, `--command COMMAND` -被执行的命令无法控制终端。所以,此选项不能用于执行需要控制 TTY 的交互式程序。 -``` +> 使用 `-c` 选项指定由 Shell 调用的命令。 + +> 被执行的命令无法控制终端。所以,此选项不能用于执行需要控制 TTY 的交互式程序。 参考示例: @@ -90,11 +72,11 @@ su [target-user] -c [command-to-run] 示例中的 `shell` 类型将会被目标用户在 `/etc/passwd` 文件中定义的登录 shell 类型所替代。 -### Sudo vs Su +### sudo vs. su 现在,我们已经讨论了关于 `su` 命令的基础知识,是时候来探讨一下 `sudo` 和 `su` 命令之间的区别了。 -### 关于密码 +#### 关于密码 两个命令的最大区别是:`sudo` 命令需要输入当前用户的密码,`su` 命令需要输入 root 用户的密码。 @@ -102,28 +84,27 @@ su [target-user] -c [command-to-run] 此外,如果要撤销特定用户的超级用户/root 用户的访问权限,唯一的办法就是更改 root 密码,然后再告知所有其他用户新的 root 密码。 -而使用 `sudo` 命令就不一样了,你可以很好的处理以上的两种情况。鉴于 `sudo` 命令要求输入的是其他用户的密码,所以,不需要共享 root 密码。同时,想要阻止特定用户访问 root 权限,只需要调整 `sudoers` 文件中的相应配置即可。 +而使用 `sudo` 命令就不一样了,你可以很好的处理以上的两种情况。鉴于 `sudo` 命令要求输入的是其他用户自己的密码,所以,不需要共享 root 密码。同时,想要阻止特定用户访问 root 权限,只需要调整 `sudoers` 文件中的相应配置即可。 -### 默认行为 +#### 默认行为 -两个命令之间的另外一个区别是默认行为。`sudo` 命令只允许使用提升的权限运行单个命令,而 `su` 命令会启动一个新的 shell,同时允许使用 root 权限运行尽可能多的命令,直到显示退出登录。 +两个命令之间的另外一个区别是其默认行为。`sudo` 命令只允许使用提升的权限运行单个命令,而 `su` 命令会启动一个新的 shell,同时允许使用 root 权限运行尽可能多的命令,直到明确退出登录。 -因此,`su` 命令的默认行为是有风险的,因为用户很有可能会忘记他们正在以 root 用户身份进行工作,于是,无意中做出了一些不可恢复的更改(例如:对错误的目录运行 `rm -rf` 命令)。关于为什么不鼓励以 root 用户身份进行工作的详细内容,请参考[这里][10] +因此,`su` 命令的默认行为是有风险的,因为用户很有可能会忘记他们正在以 root 用户身份进行工作,于是,无意中做出了一些不可恢复的更改(例如:对错误的目录运行 `rm -rf` 命令!)。关于为什么不鼓励以 root 用户身份进行工作的详细内容,请参考[这里][10]。 -### 日志记录 +#### 日志记录 -尽管 `sudo` 命令是以目标用户(默认情况下是 root 用户)的身份执行命令,但是他们会使用 sudoer 所配置的用户名来记录是谁执行命令。而 `su` 命令是无法直接跟踪记录用户切换到 root 用户之后执行了什么操作。 +尽管 `sudo` 命令是以目标用户(默认情况下是 root 用户)的身份执行命令,但是它们会使用 `sudoer` 所配置的用户名来记录是谁执行命令。而 `su` 命令是无法直接跟踪记录用户切换到 root 用户之后执行了什么操作。 -### 灵活性 +#### 灵活性 -`sudo` 命令会比 `su` 命令灵活很多,因为你甚至可以限制 sudo 用户可以访问哪些命令。换句话说,用户通过 `sudo` 命令只能访问他们工作需要的命令。而 `su` 命令让用户有权限做任何事情。 +`sudo` 命令比 `su` 命令灵活很多,因为你甚至可以限制 sudo 用户可以访问哪些命令。换句话说,用户通过 `sudo` 命令只能访问他们工作需要的命令。而 `su` 命令让用户有权限做任何事情。 -### Sudo su +#### sudo su 大概是因为使用 `su` 命令或直接以 root 用户身份登录有风险,所以,一些 Linux 发行版(如 Ubuntu)默认禁用 root 用户帐户。鼓励用户在需要 root 权限时使用 `sudo` 命令。 -However, you can still do 'su' successfully, i.e, without entering the root password. All you need to do is to run the following command: -然而,您还是可以成功执行 `su` 命令,即不用输入 root 用户的密码。运行以下命令: +然而,您还是可以成功执行 `su` 命令,而不用输入 root 用户的密码。运行以下命令: ``` sudo su @@ -131,7 +112,7 @@ sudo su 由于你使用 `sudo` 运行命令,你只需要输入当前用户的密码。所以,一旦完成操作,`su` 命令将会以 root 用户身份运行,这意味着它不会再要求输入任何密码。 -** PS **:如果你想在系统中启用 root 用户帐户(虽然强烈反对,但你还是可以使用 `sudo` 命令或 `sudo su` 命令),你必须手动设置 root 用户密码 可以使用以下命令: +**PS**:如果你想在系统中启用 root 用户帐户(强烈反对,因为你可以使用 `sudo` 命令或 `sudo su` 命令),你必须手动设置 root 用户密码,可以使用以下命令: ``` sudo passwd root @@ -139,7 +120,7 @@ sudo passwd root ### 结论 -这篇文章以及之前的教程(其中侧重于 `sudo` 命令)应该能给你一个比较好的建议,当你需要可用的工具来提升(或一组完全不同的)权限来执行任务时。 如果您也想分享关于 `su` 或 `sudo` 的相关内容或者经验,欢迎您在下方进行评论。 +当你需要可用的工具来提升(或一组完全不同的)权限来执行任务时,这篇文章以及之前的教程(其中侧重于 `sudo` 命令)应该能给你一个比较好的建议。 如果您也想分享关于 `su` 或 `sudo` 的相关内容或者经验,欢迎您在下方进行评论。 -------------------------------------------------------------------------------- @@ -147,7 +128,7 @@ via: https://www.howtoforge.com/tutorial/sudo-vs-su/ 作者:[Himanshu Arora][a] 译者:[zhb127](https://github.com/zhb127) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From b8e2479c6f23520b3290d044327317506165b7e4 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 14 Apr 2017 17:40:42 +0800 Subject: [PATCH 11/37] PUB:20170217 Understanding the difference between sudo and su.md @zhb127 --- .../20170217 Understanding the difference between sudo and su.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170217 Understanding the difference between sudo and su.md (100%) diff --git a/translated/tech/20170217 Understanding the difference between sudo and su.md b/published/20170217 Understanding the difference between sudo and su.md similarity index 100% rename from translated/tech/20170217 Understanding the difference between sudo and su.md rename to published/20170217 Understanding the difference between sudo and su.md From 89b43f0059dab89d47f5e5c8008998733a4b6f68 Mon Sep 17 00:00:00 2001 From: ictlyh Date: Fri, 14 Apr 2017 22:00:11 +0800 Subject: [PATCH 12/37] Translating 2 posts --- ...all Jenkins Automation Server with Apache on Ubuntu 16.04.md | 2 +- ...0170319 How to Add a New Disk to an Existing Linux Server.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/tech/20161125 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04.md b/sources/tech/20161125 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04.md index abe2cbcc40..c1f983a017 100644 --- a/sources/tech/20161125 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04.md +++ b/sources/tech/20161125 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04.md @@ -1,4 +1,4 @@ -willcoderwang 翻译中 +ictlyh 接手 willcoderwang 翻译 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04 ============================================================ diff --git a/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md b/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md index c4d32941bc..699fc42b8c 100644 --- a/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md +++ b/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md @@ -1,3 +1,4 @@ +ictlyh Translating How to Add a New Disk to an Existing Linux Server ============================================================ From 3e0dda90f0f7c24aa9133911a66108061a79b7a8 Mon Sep 17 00:00:00 2001 From: Yoo-4x Date: Fri, 14 Apr 2017 23:35:32 +0800 Subject: [PATCH 13/37] translating --- sources/tech/20170312 OpenGL Go Tutorial Part 1.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20170312 OpenGL Go Tutorial Part 1.md b/sources/tech/20170312 OpenGL Go Tutorial Part 1.md index 56adf60616..06b80217ec 100644 --- a/sources/tech/20170312 OpenGL Go Tutorial Part 1.md +++ b/sources/tech/20170312 OpenGL Go Tutorial Part 1.md @@ -1,3 +1,5 @@ +Yoo-4x Translating + OpenGL & Go Tutorial Part 1: Hello, OpenGL ============================================================ From e8cdd7843a24352eace38680c7ea801f684e9758 Mon Sep 17 00:00:00 2001 From: wxy Date: Sat, 15 Apr 2017 10:07:00 +0800 Subject: [PATCH 14/37] PUB:20170110 Improve your programming skills with Exercism.md @geekpi @jasminepeng --- ...e your programming skills with Exercism.md | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) rename {translated/tech => published}/20170110 Improve your programming skills with Exercism.md (56%) diff --git a/translated/tech/20170110 Improve your programming skills with Exercism.md b/published/20170110 Improve your programming skills with Exercism.md similarity index 56% rename from translated/tech/20170110 Improve your programming skills with Exercism.md rename to published/20170110 Improve your programming skills with Exercism.md index 82a0d619f3..cad94fa09e 100644 --- a/translated/tech/20170110 Improve your programming skills with Exercism.md +++ b/published/20170110 Improve your programming skills with Exercism.md @@ -1,38 +1,39 @@ 使用 Exercism 提升你的编程技巧 ============================================================ -### 这些练习目前已经支持 33 种编程语言了。 +> 这些练习目前已经支持 33 种编程语言了。 ![Improve your programming skills with Exercism ](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/code2.png?itok=CVgC8tlK "Improve your programming skills with Exercism ") + >图片提供: opensource.com -我们中的很多人有 2017 年的目标,将提高编程能力或学习如何编程放在第一位。虽然我们有许多资源可以访问,但练习独立于特定职业的代码开发的艺术还是需要一些规划。[Exercism.io][1] 就是为此目的而设计的一种资源。 +我们中的很多人的 2017 年目标,将提高编程能力或学习如何编程放在第一位。虽然我们有许多资源可以访问,但练习独立于特定职业的代码开发的艺术还是需要一些规划。[Exercism.io][1] 就是为此目的而设计的一种资源。 -Exercism 是一个 [开源][2] 项目和服务,通过发现和协作,帮助人们提高他们的编程技能。Exercism 提供了几十种不同编程语言的练习。实践者完成每个练习,并获得反馈,从而可以从他们的同行小组的经验中学习。 +Exercism 是一个 [开源][2] 的项目和服务,通过发现和协作,帮助人们提高他们的编程技能。Exercism 提供了几十种不同编程语言的练习。实践者完成每个练习,并获得反馈,从而可以从他们的同行小组的经验中学习。 这里有这么多同行! Exercism 在 2016 年留下了一些令人印象深刻的统计: -* 有来自201个不同国家的参与者 +* 有来自 201 个不同国家的参与者 * 自 2013 年 6 月以来,29,000 名参与者提交了练习,其中仅在 2016 年就有 15,500 名参加者提交练习 * 自 2013 年 6 月以来,15,000 名参与者就练习解决方案提供反馈,其中 2016 年有 5,500 人提供反馈 * 每月 50,000 名访客,每周超过 12,000 名访客 -* 目前练习支持 33 种编程语言,另外 22 种语言在筹备工作中 +* 目前的练习已经支持 33 种编程语言,另外 22 种语言在筹备工作中 -该项目为所有级别的参与者提供了一系列小小的胜利,使他们能够“即使在低水平也能发展到高度流利”,Exercism 的创始人 [Katrina Owen][3] 这样说到。Exercism 并不旨在教导学员成为一名职业程序员,但它的练习使他们对一种语言及其瑕疵有深刻的了解。这种熟悉性消除了学习者对语言的认知负担(流利),使他们能够专注于更困难的架构和最佳实践(熟练)的问题。 +该项目为各种级别的参与者提供了一系列小小的挑战,使他们能够“即使在低水平也能发展到高度谙熟”,Exercism 的创始人 [Katrina Owen][3] 这样说到。Exercism 并不旨在教导学员成为一名职业程序员,但它的练习使他们对一种语言及其瑕疵有深刻的了解。这种熟悉性消除了学习者对语言的认知负担(使之更谙熟),使他们能够专注于更困难的架构和最佳实践的问题。 -Exercism 通过一系列练习(还有什么?)来做到这一点。程序员下载[命令行客户端][4],检索第一个练习,添加完成练习的代码,然后提交解决方案。提交解决方案后,程序员可以研究他人的解决方案,并学习到对同一个问题不同的解决方式。更重要的是,每个解决方案都会收到来自其他参与者的反馈。 +Exercism 通过一系列练习(或者还有别的?)来做到这一点。程序员下载[命令行客户端][4],检索第一个练习,添加完成练习的代码,然后提交解决方案。提交解决方案后,程序员可以研究他人的解决方案,并学习到对同一个问题不同的解决方式。更重要的是,每个解决方案都会收到来自其他参与者的反馈。 -反馈是 Exercism 的超级力量。鼓励所有参与者不仅接收反馈而且提供反馈。根据 Owen 说的,Exercism 的社区成员提供反馈比完成练习学到更多。她说:“这是一个强大的学习经验,你被迫发表内心感受,并检查你的假设、习惯和偏见”。她还指出,反馈可以有多种形式。 +反馈是 Exercism 的超级力量。鼓励所有参与者不仅接收反馈而且提供反馈。根据 Owen 说的,Exercism 的社区成员提供反馈比完成练习学到更多。她说:“这是一个强大的学习经验,你需要发表内心感受,并检查你的假设、习惯和偏见”。她还指出,反馈可以有多种形式。 -欧文说:“只需进入,观察并问问题”。 +欧文说:“只需进入,观察并发问”。 -那些刚刚接触编程,甚至只是一种特定语言的人,可以通过质疑假设来提供有价值的反馈,同时通过协作和对话来学习。 +那些刚刚接触编程,甚至只是接触了一种特定语言的人,可以通过预设好的问题来提供有价值的反馈,同时通过协作和对话来学习。 -除了对新语言的 “微课”学习bite-sized learning 之外,Exercism 本身还强烈支持和鼓励项目的新贡献者。在 [SitePoint.com][5] 的一篇文章中,欧文强调:“如果你想为开源贡献代码,你所需要的技能水平只要‘够用’即可。” Exercism 不仅鼓励新的贡献者,它还尽可能地帮助新贡献者发布他们项目中的第一个补丁。到目前为止,有近 1000 人是[ Exercism 项目][6]的贡献者。 +除了对新语言的 “微课”学习bite-sized learning 之外,Exercism 本身还强烈支持和鼓励项目的新贡献者。在 [SitePoint.com][5] 的一篇文章中,欧文强调:“如果你想为开源贡献代码,你所需要的技能水平只要‘够用’即可。” Exercism 不仅鼓励新的贡献者,它还尽可能地帮助新贡献者发布他们项目中的第一个补丁。到目前为止,有近 1000 人成为 [Exercism 项目][6]的贡献者。 -新贡献者会有大量工作让他们忙碌。 Exercism 目前正在审查[其语言轨道的健康状况][7],目的是使所有轨道可持续并避免维护者的倦怠。它还在寻求[捐赠][8]和赞助,聘请设计师提高网站的可用性。 +新贡献者会有大量工作让他们忙碌。 Exercism 目前正在审查[其语言发展轨迹的健康状况][7],目的是使所有发展轨迹可持续并避免维护者的倦怠。它还在寻求[捐赠][8]和赞助,聘请设计师提高网站的可用性。 -Owen 说:“这些改进对于网站的健康以及为了 Exercism 参与者的发展是有必要的,这些变化还鼓励新贡献者加入并简化了加入的途径。” 她说:“如果我们可以重新设计,产品方面将更加可维护。。。当用户体验一团糟,华丽的代码一点用也没有”。该项目有一个非常活跃的[讨论仓库][9],这里社区成员合作来发现最好的新方法和功能。 +Owen 说:“这些改进对于网站的健康以及为了 Exercism 参与者的发展是有必要的,这些变化还鼓励新贡献者加入并简化了加入的途径。” 她说:“如果我们可以重新设计,产品方面将更加可维护……当用户体验一团糟时,华丽的代码一点用也没有”。该项目有一个非常活跃的[讨论仓库][9],这里社区成员合作来发现最好的新方法和功能。 那些想关注项目但还没有参与的人可以关注[邮件列表][10]。 @@ -42,10 +43,12 @@ Owen 说:“这些改进对于网站的健康以及为了 Exercism 参与者 ![](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/vmb_helvetica_sm.png?itok=mSb3xriS) -VM(Vicky)Brasseur - VM(也称为 Vicky)是技术人员、项目、流程、产品和 p^Hbusinesses 的经理。在她超过 18 年的科技行业从业中,她曾是分析师、程序员、产品经理、软件工程经理和软件工程总监。 目前,她是 Hewlett Packard Enterprise 上游开源开发团队的高级工程经理。 VM 的博客在 anonymoushash.vmbrasseur.com,tweets 在 @vmbrasseur。 +VM(Vicky)Brasseur - VM(也称为 Vicky)是技术人员、项目、流程、产品和 p\^Hbusinesses 的经理。在她超过 18 年的科技行业从业中,她曾是分析师、程序员、产品经理、软件工程经理和软件工程总监。 目前,她是 Hewlett Packard Enterprise 上游开源开发团队的高级工程经理。 VM 的博客在 anonymoushash.vmbrasseur.com,tweets 在 @vmbrasseur。 -------------------------------------------------------------------------------- +via: https://opensource.com/article/17/1/exercism-learning-programming + 作者:[VM (Vicky) Brasseur][a] 译者:[geekpi](https://github.com/geekpi) 校对:[jasminepeng](https://github.com/jasminepeng) From d579575fcd07e21fa0b7692bd7da6fd94d9f57ae Mon Sep 17 00:00:00 2001 From: xiaow6 Date: Sat, 15 Apr 2017 10:50:27 +0800 Subject: [PATCH 15/37] translated by xiaow6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 专有名词较多,还请校对多核对。脱稿太久了不好意思。 --- sources/tech/20170111 Git in 2016.md | 726 ------------------------ translated/tech/20170111 Git in 2016.md | 682 ++++++++++++++++++++++ 2 files changed, 682 insertions(+), 726 deletions(-) delete mode 100644 sources/tech/20170111 Git in 2016.md create mode 100644 translated/tech/20170111 Git in 2016.md diff --git a/sources/tech/20170111 Git in 2016.md b/sources/tech/20170111 Git in 2016.md deleted file mode 100644 index dd82429fae..0000000000 --- a/sources/tech/20170111 Git in 2016.md +++ /dev/null @@ -1,726 +0,0 @@ - - -tranlating by xiaow6 -Git in 2016 -============================================================ - - ![](https://cdn-images-1.medium.com/max/2000/1*1SiSsLMsNSyAk6khb63W9g.png) - - -Git had a  _huge_  year in 2016, with five feature releases[¹][57] ( _v2.7_  through  _v2.11_ ) and sixteen patch releases[²][58]. 189 authors[³][59] contributed 3,676 commits[⁴][60] to `master`, which is up 15%[⁵][61] over 2015! In total, 1,545 files were changed with 276,799 lines added and 100,973 lines removed[⁶][62]. - -However, commit counts and LOC are pretty terrible ways to measure productivity. Until deep learning develops to the point where it can qualitatively grok code, we’re going to be stuck with human judgment as the arbiter of productivity. - -With that in mind, I decided to put together a retrospective of sorts that covers changes improvements made to six of my favorite Git features over the course of the year. This article is pretty darn long for a Medium post, so I will forgive you if you want to skip ahead to a feature that particularly interests you: - -* [Rounding out the ][41]`[git worktree][25]`[ command][42] -* [More convenient ][43]`[git rebase][26]`[ options][44] -* [Dramatic performance boosts for ][45]`[git lfs][27]` -* [Experimental algorithms and better defaults for ][46]`[git diff][28]` -* `[git submodules][29]`[ with less suck][47] -* [Nifty enhancements to ][48]`[git stash][30]` - -Before we begin, note that many operating systems ship with legacy versions of Git, so it’s worth checking that you’re on the latest and greatest. If running `git --version` from your terminal returns anything less than Git `v2.11.0`, head on over to Atlassian's quick guide to [upgrade or install Git][63] on your platform of choice. - -### [`Citation` needed] - -One more quick stop before we jump into the qualitative stuff: I thought I’d show you how I generated the statistics from the opening paragraph (and the rather over-the-top cover image). You can use the commands below to do a quick  _year in review_  for your own repositories as well! - -``` -¹ Tags from 2016 matching the form vX.Y.0 -``` - -``` -$ git for-each-ref --sort=-taggerdate --format \ -'%(refname) %(taggerdate)' refs/tags | grep "v\d\.\d*\.0 .* 2016" -``` - -``` -² Tags from 2016 matching the form vX.Y.Z -``` - -``` -$ git for-each-ref --sort=-taggerdate --format '%(refname) %(taggerdate)' refs/tags | grep "v\d\.\d*\.[^0] .* 2016" -``` - -``` -³ Commits by author in 2016 -``` - -``` -$ git shortlog -s -n --since=2016-01-01 --until=2017-01-01 -``` - -``` -⁴ Count commits in 2016 -``` - -``` -$ git log --oneline --since=2016-01-01 --until=2017-01-01 | wc -l -``` - -``` -⁵ ... and in 2015 -``` - -``` -$ git log --oneline --since=2015-01-01 --until=2016-01-01 | wc -l -``` - -``` -⁶ Net LOC added/removed in 2016 -``` - -``` -$ git diff --shortstat `git rev-list -1 --until=2016-01-01 master` \ - `git rev-list -1 --until=2017-01-01 master` -``` - -The commands above were are run on Git’s `master` branch, so don’t represent any unmerged work on outstanding branches. If you use these command, remember that commit counts and LOC are not metrics to live by. Please don’t use them to rate the performance of your teammates! - -And now, on with the retrospective… - -### Rounding out Git worktrees - -The `git worktree` command first appeared in Git v2.5 but had some notable enhancements in 2016\. Two valuable new features were introduced in v2.7 — the `list` subcommand, and namespaced refs for bisecting — and the `lock`/`unlock` subcommands were implemented in v2.10. - -#### What’s a worktree again? - -The `[git worktree][49]` command lets you check out and work on multiple repository branches in separate directories simultaneously. For example, if you need to make a quick hotfix but don't want to mess with your working copy, you can check out a new branch in a new directory with: - -``` -$ git worktree add -b hotfix/BB-1234 ../hotfix/BB-1234 -Preparing ../hotfix/BB-1234 (identifier BB-1234) -HEAD is now at 886e0ba Merged in bedwards/BB-13430-api-merge-pr (pull request #7822) -``` - -Worktrees aren’t just for branches. You can check out multiple tags as different worktrees in order to build or test them in parallel. For example, I created worktrees from the Git v2.6 and v2.7 tags in order to examine the behavior of different versions of Git: - -``` -$ git worktree add ../git-v2.6.0 v2.6.0 -Preparing ../git-v2.6.0 (identifier git-v2.6.0) -HEAD is now at be08dee Git 2.6 -``` - -``` -$ git worktree add ../git-v2.7.0 v2.7.0 -Preparing ../git-v2.7.0 (identifier git-v2.7.0) -HEAD is now at 7548842 Git 2.7 -``` - -``` -$ git worktree list -/Users/kannonboy/src/git 7548842 [master] -/Users/kannonboy/src/git-v2.6.0 be08dee (detached HEAD) -/Users/kannonboy/src/git-v2.7.0 7548842 (detached HEAD) -``` - -``` -$ cd ../git-v2.7.0 && make -``` - -You could use the same technique to build and run different versions of your own applications side-by-side. - -#### Listing worktrees - -The `git worktree list` subcommand (introduced in Git v2.7) displays all of the worktrees associated with a repository: - -``` -$ git worktree list -/Users/kannonboy/src/bitbucket/bitbucket 37732bd [master] -/Users/kannonboy/src/bitbucket/staging d5924bc [staging] -/Users/kannonboy/src/bitbucket/hotfix-1234 37732bd [hotfix/1234] -``` - -#### Bisecting worktrees - -`[git bisect][50]` is a neat Git command that lets you perform a binary search of your commit history. It's usually used to find out which commit introduced a particular regression. For example, if a test is failing on the tip commit of my `master` branch, I can use `git bisect` to traverse the history of my repository looking for the commit that first broke it: - -``` -$ git bisect start -``` - -``` -# indicate the last commit known to be passing the tests -# (e.g. the latest release tag) -$ git bisect good v2.0.0 -``` - -``` -# indicate a known broken commit (e.g. the tip of master) -$ git bisect bad master -``` - -``` -# tell git bisect a script/command to run; git bisect will -# find the oldest commit between "good" and "bad" that causes -# this script to exit with a non-zero status -$ git bisect run npm test -``` - -Under the hood, bisect uses refs to track the good and bad commits used as the upper and lower bounds of the binary search range. Unfortunately for worktree fans, these refs were stored under the generic `.git/refs/bisect`namespace, meaning that `git bisect` operations that are run in different worktrees could interfere with each other. - -As of v2.7, the bisect refs have been moved to`.git/worktrees/$worktree_name/refs/bisect`, so you can run bisect operations concurrently across multiple worktrees. - -#### Locking worktrees - -When you’re finished with a worktree, you can simply delete it and then run `git worktree prune` or wait for it to be garbage collected automatically. However, if you're storing a worktree on a network share or removable media, then it will be cleaned up if the worktree directory isn't accessible during pruning — whether you like it or not! Git v2.10 introduced the `git worktree lock` and `unlock` subcommands to prevent this from happening: - -``` -# to lock the git-v2.7 worktree on my USB drive -$ git worktree lock /Volumes/Flash_Gordon/git-v2.7 --reason \ -"In case I remove my removable media" -``` - -``` -# to unlock (and delete) the worktree when I'm finished with it -$ git worktree unlock /Volumes/Flash_Gordon/git-v2.7 -$ rm -rf /Volumes/Flash_Gordon/git-v2.7 -$ git worktree prune -``` - -The `--reason` flag lets you leave a note for your future self, describing why the worktree is locked. `git worktree unlock` and `lock` both require you to specify the path to the worktree. Alternatively, you can `cd` to the worktree directory and run `git worktree lock .` for the same effect. - -### More Git r`ebase` options - -In March, Git v2.8 added the ability to interactively rebase whilst pulling with a `git pull --rebase=interactive`. Conversely, June's Git v2.9 release implemented support for performing a rebase exec without needing to drop into interactive mode via `git rebase -x`. - -#### Re-wah? - -Before we dive in, I suspect there may be a few readers who aren’t familiar or completely comfortable with the rebase command or interactive rebasing. Conceptually, it’s pretty simple, but as with many of Git’s powerful features, the rebase is steeped in some complex-sounding terminology. So, before we dive in, let’s quickly review what a rebase is. - -Rebasing means rewriting one or more commits on a particular branch. The `git rebase` command is heavily overloaded, but the name rebase originates from the fact that it is often used to change a branch's base commit (the commit that you created the branch from). - -Conceptually, rebase unwinds the commits on your branch by temporarily storing them as a series of patches, and then reapplying them in order on top of the target commit. - - - ![](https://cdn-images-1.medium.com/max/800/1*mgyl38slmqmcE4STS56nXA.gif) - -Rebasing a feature branch on master (`git rebase master`) is a great way to "freshen" your feature branch with the latest changes from master. For long-lived feature branches, regular rebasing minimizes the chance and severity of conflicts down the road. - -Some teams also choose to rebase immediately before merging their changes onto master in order to achieve a fast-forward merge (`git merge --ff ` ). Fast-forwarding merges your commits onto master by simply making the master ref point at the tip of your rewritten branch without creating a merge commit: - - ![](https://cdn-images-1.medium.com/max/800/1*QXa3znQiuNWDjxroX628VA.gif) - -Rebasing is so convenient and powerful that it has been baked into some other common Git commands, such as `git pull`. If you have some unpushed changes on your local master branch, running `git pull` to pull your teammates' changes from the origin will create an unnecessary merge commit: - - ![](https://cdn-images-1.medium.com/max/800/1*IxDdJ5CygvSWdD8MCNpZNg.gif) - -This is kind of messy, and on busy teams, you’ll get heaps of these unnecessary merge commits. `git pull --rebase` rebases your local changes on top of your teammates' without creating a merge commit: - - - ![](https://cdn-images-1.medium.com/max/800/1*HcroDMwBE9m21-hOeIwRmw.gif) - -This is pretty neat! Even cooler, Git v2.8 introduced a feature that lets you rebase  _interactively_  whilst pulling. - -#### Interactive rebasing - -Interactive rebasing is a more powerful form of rebasing. Like a standard rebase, it rewrites commits, but it also gives you a chance to modify them interactively as they are reapplied onto the new base. - -When you run `git rebase --interactive` (or `git pull --rebase=interactive`), you'll be presented with a list of commits in your text editor of choice: - -``` -$ git rebase master --interactive -``` - -``` -pick 2fde787 ACE-1294: replaced miniamalCommit with string in test -pick ed93626 ACE-1294: removed pull request service from test -pick b02eb9a ACE-1294: moved fromHash, toHash and diffType to batch -pick e68f710 ACE-1294: added testing data to batch email file -``` - -``` -# Rebase f32fa9d..0ddde5f onto f32fa9d (4 commands) -# -# Commands: -# p, pick = use commit -# r, reword = use commit, but edit the commit message -# e, edit = use commit, but stop for amending -# s, squash = use commit, but meld into previous commit -# f, fixup = like "squash", but discard this commit's log message -# x, exec = run command (the rest of the line) using shell -# d, drop = remove commit -# -# These lines can be re-ordered; they are executed from top to -# bottom. -# -# If you remove a line here THAT COMMIT WILL BE LOST. -``` - -Notice that each commit has the word `pick` next to it. That's rebase-speak for, "Keep this commit as-is." If you quit your text editor now, it will perform a normal rebase as described in the last section. However, if you change `pick` to `edit` or one of the other rebase commands, rebase will let you mutate the commit before it is reapplied! There are several available rebase commands: - -* `reword`: Edit the commit message. -* `edit`: Edit the files that were committed. -* `squash`: Combine the commit with the previous commit (the one above it in the file), concatenating the commit messages. -* `fixup`: Combine the commit with the commit above it, and uses the previous commit's log message verbatim (this is handy if you created a second commit for a small change that should have been in the original commit, i.e., you forgot to stage a file). -* `exec`: Run an arbitrary shell command (we'll look at a neat use-case for this later, in the next section). -* `drop`: This kills the commit. - -You can also reorder commits within the file, which changes the order in which they’re reapplied. This is handy if you have interleaved commits that are addressing different topics and you want to use `squash` or `fixup` to combine them into logically atomic commits. - -Once you’ve set up the commands and saved the file, Git will iterate through each commit, pausing at each `reword` and `edit` for you to make your desired changes and automatically applying any `squash`, `fixup`, `exec`, and `drop` commands for you. - -#### Non-interactive exec - -When you rebase, you’re essentially rewriting history by applying each of your new commits on top of the specified base. `git pull --rebase` can be a little risky because depending on the nature of the changes from the upstream branch, you may encounter test failures or even compilation problems for certain commits in your newly created history. If these changes cause merge conflicts, the rebase process will pause and allow you to resolve them. However, changes that merge cleanly may still break compilation or tests, leaving broken commits littering your history. - -However, you can instruct Git to run your project’s test suite for each rewritten commit. Prior to Git v2.9, you could do this with a combination of `git rebase −−interactive` and the `exec` command. For example, this: - -``` -$ git rebase master −−interactive −−exec=”npm test” -``` - -…would generate an interactive rebase plan that invokes `npm test` after rewriting each commit, ensuring that your tests still pass: - -``` -pick 2fde787 ACE-1294: replaced miniamalCommit with string in test -exec npm test -pick ed93626 ACE-1294: removed pull request service from test -exec npm test -pick b02eb9a ACE-1294: moved fromHash, toHash and diffType to batch -exec npm test -pick e68f710 ACE-1294: added testing data to batch email file -exec npm test -``` - -``` -# Rebase f32fa9d..0ddde5f onto f32fa9d (4 command(s)) -``` - -In the event that a test fails, rebase will pause to let you fix the tests (and apply your changes to that commit): - -``` -291 passing -1 failing -``` - -``` -1) Host request “after all” hook: -Uncaught Error: connect ECONNRESET 127.0.0.1:3001 -… -npm ERR! Test failed. -Execution failed: npm test -You can fix the problem, and then run - git rebase −−continue -``` - -This is handy, but needing to do an interactive rebase is a bit clunky. As of Git v2.9, you can perform a non-interactive rebase exec, with: - -``` -$ git rebase master -x “npm test” -``` - -Just replace `npm test` with `make`, `rake`, `mvn clean install`, or whatever you use to build and test your project. - -#### A word of warning - -Just like in the movies, rewriting history is risky business. Any commit that is rewritten as part of a rebase will have it’s SHA-1 ID changed, which means that Git will treat it as a totally different commit. If rewritten history is mixed with the original history, you’ll get duplicate commits, which can cause a lot of confusion for your team. - -To avoid this problem, you only need to follow one simple rule: - -> _Never rebase a commit that you’ve already pushed!_ - -Stick to that and you’ll be fine. - -### Performance boosts for `Git LFS` - -[Git is a distributed version control system][64], meaning the entire history of the repository is transferred to the client during the cloning process. For projects that contain large files — particularly large files that are modified regularly _ — _ the initial clone can be expensive, as every version of every file has to be downloaded by the client. [Git LFS (Large File Storage)][65] is a Git extension developed by Atlassian, GitHub, and a few other open source contributors that reduces the impact of large files in your repository by downloading the relevant versions of them lazily. Specifically, large files are downloaded as needed during the checkout process rather than during cloning or fetching. - -Alongside Git’s five huge releases in 2016, Git LFS had four feature-packed releases of its own: v1.2 through v1.5. You could write a retrospective series on Git LFS in its own right, but for this article, I’m going to focus on one of the most important themes tackled in 2016: speed. A series of improvements to both Git and Git LFS have greatly improved the performance of transferring files to and from the server. - -#### Long-running filter processes - -When you `git add` a file, Git's system of clean filters can be used to transform the file’s contents before being written to the Git object store. Git LFS reduces your repository size by using a clean filter to squirrel away large file content in the LFS cache and adds a tiny “pointer” file to the Git object store instead. - - - ![](https://cdn-images-1.medium.com/max/800/0*Ku328eca7GLOo7sS.png) - -Smudge filters are the opposite of clean filters — hence the name. When file content is read from the Git object store during a `git checkout`, smudge filters have a chance to transform it before it’s written to the user’s working copy. The Git LFS smudge filter transforms pointer files by replacing them with the corresponding large file, either from your LFS cache or by reading through to your Git LFS store on Bitbucket. - -![](https://cdn-images-1.medium.com/max/800/0*CU60meE1lbCuivn7.png) - -Traditionally, smudge and clean filter processes were invoked once for each file that was being added or checked out. So, a project with 1,000 files tracked by Git LFS invoked the `git-lfs-smudge` command 1,000 times for a fresh checkout! While each operation is relatively quick, the overhead of spinning up 1,000 individual smudge processes is costly. - -As of Git v2.11 (and Git LFS v1.5), smudge and clean filters can be defined as long-running processes that are invoked once for the first filtered file, then fed subsequent files that need smudging or cleaning until the parent Git operation exits. [Lars Schneider][66], who contributed long-running filters to Git, neatly summarized the impact of the change on Git LFS performance: - -> The filter process is 80x faster on macOS and 58x faster on Windows for the test repo with 12k files. On Windows, that means the tests runs in 57 seconds instead of 55 minutes! - -That’s a seriously impressive performance gain! - -#### Specialized LFS clones - -Long-running smudge and clean filters are great for speeding up reads and writes to the local LFS cache, but they do little to speed up transferring of large objects to and from your Git LFS server. Each time the Git LFS smudge filter can’t find a file in the local LFS cache, it has to make two HTTP calls to retrieve it: one to locate the file and one to download it. During a `git clone`, your local LFS cache is empty, so Git LFS will naively make two HTTP calls for every LFS tracked file in your repository: - - - ![](https://cdn-images-1.medium.com/max/800/0*ViL7r3ZhkGvF0z3-.png) - -Fortunately, Git LFS v1.2 shipped the specialized `[git lfs clone][51]` command. Rather than downloading files one at a time; `git lfs clone` disables the Git LFS smudge filter, waits until the checkout is complete, and then downloads any required files as a batch from the Git LFS store. This allows downloads to be parallelized and halves the number of required HTTP requests: - - ![](https://cdn-images-1.medium.com/max/800/0*T43VA0DYTujDNgkH.png) - -### Custom Transfer Adapters - -As discussed earlier, Git LFS shipped support for long running filter processes in v1.5\. However, support for another type of pluggable process actually shipped earlier in the year. Git LFS v1.3 included support for pluggable transfer adapters so that different Git LFS hosting services could define their own protocols for transferring files to and from LFS storage. - -As of the end of 2016, Bitbucket is the only hosting service to implement their own Git LFS transfer protocol via the [Bitbucket LFS Media Adapter][67]. This was done to take advantage of a unique feature of Bitbucket’s LFS storage API called chunking. Chunking means large files are broken down into 4MB chunks before uploading or downloading. - ![](https://cdn-images-1.medium.com/max/800/1*N3SpjQZQ1Ge8OwvWrtS1og.gif) - -Chunking gives Bitbucket’s Git LFS support three big advantages: - -1. Parallelized downloads and uploads. By default, Git LFS transfers up to three files in parallel. However, if only a single file is being transferred (which is the default behavior of the Git LFS smudge filter), it is transferred via a single stream. Bitbucket’s chunking allows multiple chunks from the same file to be uploaded or downloaded simultaneously, often dramatically improving transfer speed. -2. Resumable chunk transfers. File chunks are cached locally, so if your download or upload is interrupted, Bitbucket’s custom LFS media adapter will resume transferring only the missing chunks the next time you push or pull. -3. Deduplication. Git LFS, like Git itself, is content addressable; each LFS file is identified by a SHA-256 hash of its contents. So, if you flip a single bit, the file’s SHA-256 changes and you have to re-upload the entire file. Chunking allows you to re-upload only the sections of the file that have actually changed. To illustrate, imagine we have a 41MB spritesheet for a video game tracked in Git LFS. If we add a new 2MB layer to the spritesheet and commit it, we’d typically need to push the entire new 43MB file to the server. However, with Bitbucket’s custom transfer adapter, we only need to push ~7Mb: the first 4MB chunk (because the file’s header information will have changed) and the last 3MB chunk containing the new layer we’ve just added! The other unchanged chunks are skipped automatically during the upload process, saving a huge amount of bandwidth and time. - -Customizable transfer adapters are a great feature for Git LFS, as they allow different hosts to experiment with optimized transfer protocols to suit their services without overloading the core project. - -### Better `git diff` algorithms and defaults - -Unlike some other version control systems, Git doesn’t explicitly store the fact that files have been renamed. For example, if I edited a simple Node.js application and renamed `index.js` to `app.js` and then ran `git diff`, I’d get back what looks like a file deletion and an addition: - - - ![](https://cdn-images-1.medium.com/max/800/1*ohMUBpSh_jqz2ffScJ7ApQ.png) - -I guess moving or renaming a file is technically just a delete followed by an add, but this isn’t the most human-friendly way to show it. Instead, you can use the `-M` flag to instruct Git to attempt to detect renamed files on the fly when computing a diff. For the above example, `git diff -M` gives us: - - ![](https://cdn-images-1.medium.com/max/800/1*ywYjxBc1wii5O8EhHbpCTA.png) - -The similarity index on the second line tells us how similar the content of the files compared was. By default, `-M` will consider any two files that are more than 50% similar. That is, you need to modify less than 50% of their lines to make them identical as a renamed file. You can choose your own similarity index by appending a percentage, i.e., `-M80%`. - -As of Git v2.9, the `git diff` and `git log` commands will both detect renames by default as if you'd passed the `-M` flag. If you dislike this behavior (or, more realistically, are parsing the diff output via a script), then you can disable it by explicitly passing the `−−no-renames` flag. - -#### Verbose Commits - -Do you ever invoke `git commit` and then stare blankly at your shell trying to remember all the changes you just made? The verbose flag is for you! - -Instead of: - -``` -Ah crap, which dependency did I just rev? -``` - -``` -# Please enter the commit message for your changes. Lines starting -# with ‘#’ will be ignored, and an empty message aborts the commit. -# On branch master -# Your branch is up-to-date with ‘origin/master’. -# -# Changes to be committed: -# new file: package.json -# -``` - -…you can invoke `git commit −−verbose` to view an inline diff of your changes. Don’t worry, it won’t be included in your commit message: - - - ![](https://cdn-images-1.medium.com/max/800/1*1vOYE2ow3ZDS8BP_QfssQw.png) - -The `−−verbose` flag isn’t new, but as of Git v2.9 you can enable it permanently with `git config --global commit.verbose true`. - -#### Experimental Diff Improvements - -`git diff` can produce some slightly confusing output when the lines before and after a modified section are the same. This can happen when you have two or more similarly structured functions in a file. For a slightly contrived example, imagine we have a JS file that contains a single function: - -``` -/* @return {string} "Bitbucket" */ -function productName() { - return "Bitbucket"; -} -``` - -Now imagine we’ve committed a change that prepends  _another_  function that does something similar: - -``` -/* @return {string} "Bitbucket" */ -function productId() { - return "Bitbucket"; -} -``` - -``` -/* @return {string} "Bitbucket" */ -function productName() { - return "Bitbucket"; -} -``` - -You’d expect `git diff` to show the top five lines as added, but it actually incorrectly attributes the very first line to the original commit: - - - ![](https://cdn-images-1.medium.com/max/800/1*9C7DWMObGHMEqD-QFGHmew.png) - -The wrong comment is included in the diff! Not the end of the world, but the couple of seconds of cognitive overhead from the  _Whaaat?_  every time this happens can add up. - -In December, Git v2.11 introduced a new experimental diff option, `--indent-heuristic`, that attempts to produce more aesthetically pleasing diffs: - - - ![](https://cdn-images-1.medium.com/max/800/1*UyWZ6JjC-izDquyWCA4bow.png) - -Under the hood, `--indent-heuristic` cycles through the possible diffs for each change and assigns each a “badness” score. This is based on heuristics like whether the diff block starts and ends with different levels of indentation (which is aesthetically bad) and whether the diff block has leading and trailing blank lines (which is aesthetically pleasing). Then, the block with the lowest badness score is output. - -This feature is experimental, but you can test it out ad-hoc by applying the `--indent-heuristic` option to any `git diff` command. Or, if you like to live on the bleeding edge, you can enable it across your system with: - -``` -$ git config --global diff.indentHeuristic true -``` - -### Submodules with less suck - -Submodules allow you to reference and include other Git repositories from inside your Git repository. This is commonly used by some projects to manage source dependencies that are also tracked in Git, or by some companies as an alternative to a [monorepo][68] containing a collection of related projects. - -Submodules get a bit of a bad rap due to some usage complexities and the fact that it’s reasonably easy to break them with an errant command. - - - ![](https://cdn-images-1.medium.com/max/800/1*xNffiElY7BZNMDM0jm0JNQ.gif) - -However, they do have their uses and are, I think, still the best choice for vendoring dependencies. Fortunately, 2016 was a great year to be a submodule user, with some significant performance and feature improvements landing across several releases. - -#### Parallelized fetching - -When cloning or fetching a repository, appending the `--recurse-submodules`option means any referenced submodules will be cloned or updated, as well. Traditionally, this was done serially, with each submodule being fetched one at a time. As of Git v2.8, you can append the `--jobs=n` option to fetch submodules in  _n_  parallel threads. - -I recommend configuring this option permanently with: - -``` -$ git config --global submodule.fetchJobs 4 -``` - -…or whatever degree of parallelization you choose to use. - -#### Shallow submodules - -Git v2.9 introduced the `git clone -−shallow-submodules` flag. It allows you to grab a full clone of your repository and then recursively shallow clone any referenced submodules to a depth of one commit. This is useful if you don’t need the full history of your project’s dependencies. - -For example, consider a repository with a mixture of submodules containing vendored dependencies and other projects that you own. You may wish to clone with shallow submodules initially and then selectively deepen the few projects you want to work with. - -Another scenario would be configuring a continuous integration or deployment job. Git needs the super repository as well as the latest commit from each of your submodules in order to actually perform the build. However, you probably don’t need the full history for every submodule, so retrieving just the latest commit will save you both time and bandwidth. - -#### Submodule alternates - -The `--reference` option can be used with `git clone` to specify another local repository as an alternate object store to save recopying objects over the network that you already have locally. The syntax is: - -``` -$ git clone --reference -``` - -As of Git v2.11, you can use the `--reference` option in combination with `--recurse-submodules` to set up submodule alternates pointing to submodules from another local repository. The syntax is: - -``` -$ git clone --recurse-submodules --reference -``` - -This can potentially save a huge amount of bandwidth and local disk but it will fail if the referenced local repository does not have all the required submodules of the remote repository that you’re cloning from. - -Fortunately, the handy `--reference-if-able` option will fail gracefully and fall back to a normal clone for any submodules that are missing from the referenced local repository: - -``` -$ git clone --recurse-submodules --reference-if-able \ - -``` - -#### Submodule diffs - -Prior to Git v2.11, Git had two modes for displaying diffs of commits that updated your repository’s submodules: - -`git diff --submodule=short` displays the old commit and new commit from the submodule referenced by your project (this is also the default if you omit the `--submodule` option altogether): - - ![](https://cdn-images-1.medium.com/max/800/1*K71cJ30NokO5B69-a470NA.png) - -`git diff --submodule=log` is slightly more verbose, displaying the summary line from the commit message of any new or removed commits in the updated submodule: - - - ![](https://cdn-images-1.medium.com/max/800/1*frvsd_T44De8_q0uvNHB1g.png) - -Git v2.11 introduces a third much more useful option: `--submodule=diff`. This displays a full diff of all changes in the updated submodule: - - ![](https://cdn-images-1.medium.com/max/800/1*nPhJTjP8tcJ0cD8s3YOmjw.png) - -### Nifty enhancements to `git stash` - -Unlike submodules, `[git stash][52]` is almost universally beloved by Git users. `git stash` temporarily shelves (or  _stashes_ ) changes you've made to your working copy so you can work on something else, and then come back and re-apply them later on. - -#### Autostash - -If you’re a fan of `git rebase`, you might be familiar with the `--autostash`option. It automatically stashes any local changes made to your working copy before rebasing and reapplies them after the rebase is completed. - -``` -$ git rebase master --autostash -Created autostash: 54f212a -HEAD is now at 8303dca It's a kludge, but put the tuple from the database in the cache. -First, rewinding head to replay your work on top of it... -Applied autostash. -``` - -This is handy, as it allows you to rebase from a dirty worktree. There’s also a handy config flag named `rebase.autostash` to make this behavior the default, which you can enable globally with: - -``` -$ git config --global rebase.autostash true -``` - -`rebase.autostash` has actually been available since [Git v1.8.4][69], but v2.7 introduces the ability to cancel this flag with the `--no-autostash` option. If you use this option with unstaged changes, the rebase will abort with a dirty worktree warning: - -``` -$ git rebase master --no-autostash -Cannot rebase: You have unstaged changes. -Please commit or stash them. -``` - -#### Stashes as Patches - -Speaking of config flags, Git v2.7 also introduces `stash.showPatch`. The default behavior of `git stash show` is to display a summary of your stashed files. - -``` -$ git stash show -package.json | 2 +- -1 file changed, 1 insertion(+), 1 deletion(-) -``` - -Passing the `-p` flag puts `git stash show` into "patch mode," which displays the full diff: - - ![](https://cdn-images-1.medium.com/max/800/1*HpcT3quuKKQj9CneqPuufw.png) - -`stash.showPatch` makes this behavior the default. You can enable it globally with: - -``` -$ git config --global stash.showPatch true -``` - -If you enable `stash.showPatch` but then decide you want to view just the file summary, you can get the old behavior back by passing the `--stat` option instead. - -``` -$ git stash show --stat -package.json | 2 +- -1 file changed, 1 insertion(+), 1 deletion(-) -``` - -As an aside: `--no-patch` is a valid option but it doesn't negate `stash.showPatch` as you'd expect. Instead, it gets passed along to the underlying `git diff` command used to generate the patch, and you'll end up with no output at all! - -#### Simple Stash IDs - -If you’re a `git stash` fan, you probably know that you can shelve multiple sets of changes, and then view them with `git stash list`: - -``` -$ git stash list -stash@{0}: On master: crazy idea that might work one day -stash@{1}: On master: desperate samurai refactor; don't apply -stash@{2}: On master: perf improvement that I forgot I stashed -stash@{3}: On master: pop this when we use Docker in production -``` - -However, you may not know why Git’s stashes have such awkward identifiers (`stash@{1}`, `stash@{2}`, etc.) and may have written them off as "just one of those Git idiosyncrasies." It turns out that like many Git features, these weird IDs are actually a symptom of a very clever use (or abuse) of the Git data model. - -Under the hood, the `git stash` command actually creates a set of special commit objects that encode your stashed changes and maintains a [reflog][70]that holds references to these special commits. This is why the output from `git stash list` looks a lot like the output from the `git reflog` command. When you run `git stash apply stash@{1}`, you're actually saying, “Apply the commit at position 1 from the stash reflog.” - -As of Git v2.11, you no longer have to use the full `stash@{n}` syntax. Instead, you can reference stashes with a simple integer indicating their position in the stash reflog: - -``` -$ git stash show 1 -$ git stash apply 1 -$ git stash pop 1 -``` - -And so forth. If you’d like to learn more about how stashes are stored, I wrote a little bit about it in [this tutorial][71]. - -### <2017> - -And we’re done. Thanks for reading! I hope you enjoyed reading this behemoth as much as I enjoyed spelunking through Git’s source code, release notes, and `man` pages to write it. If you think I missed anything big, please leave a comment or let me know [on Twitter][72] and I'll endeavor to write a follow-up piece. - -As for what’s next for Git, that’s up to the maintainers and contributors (which [could be you!][73]). With ever-increasing adoption, I’m guessing that simplification, improved UX, and better defaults will be strong themes for Git in 2017\. As Git repositories get bigger and older, I suspect we’ll also see continued focus on performance and improved handling of large files, deep trees, and long histories. - -If you’re into Git and excited to meet some of the developers behind the project, consider coming along to [Git Merge][74] in Brussels in a few weeks time. I’m [speaking there][75]! But more importantly, many of the developers who maintain Git will be in attendance for the conference and the annual Git Contributors Summit, which will likely drive much of the direction for the year ahead. - -Or if you can’t wait ’til then, head over to Atlassian’s excellent selection of [Git tutorials][76] for more tips and tricks to improve your workflow. - - _If you scrolled to the end looking for the footnotes from the first paragraph, please jump to the _ [ _[Citation needed]_ ][77] _ section for the commands used to generate the stats. Gratuitous cover image generated using _ [ _instaco.de_ ][78] _ ❤️_ - --------------------------------------------------------------------------------- - -via: https://hackernoon.com/git-in-2016-fad96ae22a15#.t5c5cm48f - -作者:[Tim Pettersen][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://hackernoon.com/@kannonboy?source=post_header_lockup -[1]:https://medium.com/@g.kylafas/the-git-config-command-is-missing-a-yes-at-the-end-as-in-git-config-global-commit-verbose-yes-7e126365750e?source=responses---------1---------- -[2]:https://medium.com/@kannonboy/thanks-giorgos-fixed-f3b83c61589a?source=responses---------1---------- -[3]:https://medium.com/@TomSwirly/i-read-the-whole-thing-from-start-to-finish-415a55d89229?source=responses---------0-31--------- -[4]:https://medium.com/@g.kylafas -[5]:https://medium.com/@g.kylafas?source=responses---------1---------- -[6]:https://medium.com/@kannonboy -[7]:https://medium.com/@kannonboy?source=responses---------1---------- -[8]:https://medium.com/@TomSwirly -[9]:https://medium.com/@TomSwirly?source=responses---------0-31--------- -[10]:https://medium.com/@g.kylafas/the-git-config-command-is-missing-a-yes-at-the-end-as-in-git-config-global-commit-verbose-yes-7e126365750e?source=responses---------1----------#--responses -[11]:https://hackernoon.com/@kannonboy -[12]:https://hackernoon.com/@kannonboy?source=placement_card_footer_grid---------0-44 -[13]:https://medium.freecodecamp.com/@BillSourour -[14]:https://medium.freecodecamp.com/@BillSourour?source=placement_card_footer_grid---------1-43 -[15]:https://blog.uncommon.is/@lut4rp -[16]:https://blog.uncommon.is/@lut4rp?source=placement_card_footer_grid---------2-43 -[17]:https://medium.com/@kannonboy -[18]:https://medium.com/@kannonboy -[19]:https://medium.com/@g.kylafas/the-git-config-command-is-missing-a-yes-at-the-end-as-in-git-config-global-commit-verbose-yes-7e126365750e?source=responses---------1---------- -[20]:https://medium.com/@kannonboy/thanks-giorgos-fixed-f3b83c61589a?source=responses---------1---------- -[21]:https://medium.com/@TomSwirly/i-read-the-whole-thing-from-start-to-finish-415a55d89229?source=responses---------0-31--------- -[22]:https://hackernoon.com/setting-breakpoints-on-a-snowy-evening-df34fc3168e2?source=placement_card_footer_grid---------0-44 -[23]:https://medium.freecodecamp.com/the-code-im-still-ashamed-of-e4c021dff55e?source=placement_card_footer_grid---------1-43 -[24]:https://blog.uncommon.is/using-git-to-generate-versionname-and-versioncode-for-android-apps-aaa9fc2c96af?source=placement_card_footer_grid---------2-43 -[25]:https://hackernoon.com/git-in-2016-fad96ae22a15#fd10 -[26]:https://hackernoon.com/git-in-2016-fad96ae22a15#cc52 -[27]:https://hackernoon.com/git-in-2016-fad96ae22a15#42b9 -[28]:https://hackernoon.com/git-in-2016-fad96ae22a15#4208 -[29]:https://hackernoon.com/git-in-2016-fad96ae22a15#a5c3 -[30]:https://hackernoon.com/git-in-2016-fad96ae22a15#c230 -[31]:https://hackernoon.com/tagged/git?source=post -[32]:https://hackernoon.com/tagged/web-development?source=post -[33]:https://hackernoon.com/tagged/software-development?source=post -[34]:https://hackernoon.com/tagged/programming?source=post -[35]:https://hackernoon.com/tagged/atlassian?source=post -[36]:https://hackernoon.com/@kannonboy -[37]:https://hackernoon.com/?source=footer_card -[38]:https://hackernoon.com/setting-breakpoints-on-a-snowy-evening-df34fc3168e2?source=placement_card_footer_grid---------0-44 -[39]:https://medium.freecodecamp.com/the-code-im-still-ashamed-of-e4c021dff55e?source=placement_card_footer_grid---------1-43 -[40]:https://blog.uncommon.is/using-git-to-generate-versionname-and-versioncode-for-android-apps-aaa9fc2c96af?source=placement_card_footer_grid---------2-43 -[41]:https://hackernoon.com/git-in-2016-fad96ae22a15#fd10 -[42]:https://hackernoon.com/git-in-2016-fad96ae22a15#fd10 -[43]:https://hackernoon.com/git-in-2016-fad96ae22a15#cc52 -[44]:https://hackernoon.com/git-in-2016-fad96ae22a15#cc52 -[45]:https://hackernoon.com/git-in-2016-fad96ae22a15#42b9 -[46]:https://hackernoon.com/git-in-2016-fad96ae22a15#4208 -[47]:https://hackernoon.com/git-in-2016-fad96ae22a15#a5c3 -[48]:https://hackernoon.com/git-in-2016-fad96ae22a15#c230 -[49]:https://git-scm.com/docs/git-worktree -[50]:https://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git#Binary-Search -[51]:https://www.atlassian.com/git/tutorials/git-lfs/#speeding-up-clones -[52]:https://www.atlassian.com/git/tutorials/git-stash/ -[53]:https://hackernoon.com/@kannonboy?source=footer_card -[54]:https://hackernoon.com/?source=footer_card -[55]:https://hackernoon.com/@kannonboy?source=post_header_lockup -[56]:https://hackernoon.com/@kannonboy?source=post_header_lockup -[57]:https://hackernoon.com/git-in-2016-fad96ae22a15#c8e9 -[58]:https://hackernoon.com/git-in-2016-fad96ae22a15#408a -[59]:https://hackernoon.com/git-in-2016-fad96ae22a15#315b -[60]:https://hackernoon.com/git-in-2016-fad96ae22a15#dbfb -[61]:https://hackernoon.com/git-in-2016-fad96ae22a15#2220 -[62]:https://hackernoon.com/git-in-2016-fad96ae22a15#bc78 -[63]:https://www.atlassian.com/git/tutorials/install-git/ -[64]:https://www.atlassian.com/git/tutorials/what-is-git/ -[65]:https://www.atlassian.com/git/tutorials/git-lfs/ -[66]:https://twitter.com/kit3bus -[67]:https://confluence.atlassian.com/bitbucket/bitbucket-lfs-media-adapter-856699998.html -[68]:https://developer.atlassian.com/blog/2015/10/monorepos-in-git/ -[69]:https://blogs.atlassian.com/2013/08/what-you-need-to-know-about-the-new-git-1-8-4/ -[70]:https://www.atlassian.com/git/tutorials/refs-and-the-reflog/ -[71]:https://www.atlassian.com/git/tutorials/git-stash/#how-git-stash-works -[72]:https://twitter.com/kannonboy -[73]:https://git.kernel.org/cgit/git/git.git/tree/Documentation/SubmittingPatches -[74]:http://git-merge.com/ -[75]:http://git-merge.com/#git-aliases -[76]:https://www.atlassian.com/git/tutorials -[77]:https://hackernoon.com/git-in-2016-fad96ae22a15#87c4 -[78]:http://instaco.de/ -[79]:https://medium.com/@Medium/personalize-your-medium-experience-with-users-publications-tags-26a41ab1ee0c#.hx4zuv3mg -[80]:https://hackernoon.com/ diff --git a/translated/tech/20170111 Git in 2016.md b/translated/tech/20170111 Git in 2016.md new file mode 100644 index 0000000000..d1bf2acabd --- /dev/null +++ b/translated/tech/20170111 Git in 2016.md @@ -0,0 +1,682 @@ + +2016 Git 新视界 +============================================================ + + ![](https://cdn-images-1.medium.com/max/2000/1*1SiSsLMsNSyAk6khb63W9g.png) + +2016 年 Git 发生了 _惊天动地_ 地变化,发布了五大新特性[¹][57] (从 _v2.7_  到  _v2.11_ )和十六个补丁[²][58]。189 位作者[³][59]贡献了 3676 个提交[⁴][60]到 `master` 分支,比 2015 年多了 15%[⁵][61]!总计有 1545 个文件被修改,其中增加了 276799 行并移除了 100973 行。 + +但是,通过统计提交的数量和代码行数来衡量生产力是一种十分愚蠢的方法。除了深度研究过的开发者可以做到凭直觉来判断代码质量的地步,我们普通人来作仲裁难免会因我们常人的判断有失偏颇。 + +谨记这一条于心,我决定整理这一年里六个我最喜爱的 Git 特性涵盖的改进,来做一次分类回顾 。这篇文章作为一篇中篇推文有点太过长了,所以我不介意你们直接跳到你们特别感兴趣的特性去。 + +* [完成][41]`[git worktree][25]`[命令][42] +* [更多方便的][43]`[git rebase][26]`[选项][44] +* `[git lfs][27]`[梦幻的性能加速][45] +* `[git diff][28]`[实验性的算法和更好的默认结果][46] +* `[git submodules][29]`[差强人意][47] +* `[git stash][30]`的[90 个增强][48] + +在我们开始之前,请注意在大多数操作系统上都自带有 Git 的旧版本,所以你需要检查你是否在使用最新并且最棒的版本。如果在终端运行 `git --version` 返回的结果小于 Git `v2.11.0`,请立刻跳转到 Atlassian 的快速指南 [更新或安装 Git][63] 并根据你的平台做出选择。 + + + +###[`引用` 是需要的] + +在我们进入高质量内容之前还需要做一个短暂的停顿:我觉得我需要为你展示我是如何从公开文档(以及开篇的封面图片)生成统计信息的。你也可以使用下面的命令来对你自己的仓库做一个快速的 *年度回顾*! + +``` +¹ Tags from 2016 matching the form vX.Y.0 +``` + +``` +$ git for-each-ref --sort=-taggerdate --format \ +'%(refname) %(taggerdate)' refs/tags | grep "v\d\.\d*\.0 .* 2016" +``` + +``` +² Tags from 2016 matching the form vX.Y.Z +``` + +``` +$ git for-each-ref --sort=-taggerdate --format '%(refname) %(taggerdate)' refs/tags | grep "v\d\.\d*\.[^0] .* 2016" +``` + +``` +³ Commits by author in 2016 +``` + +``` +$ git shortlog -s -n --since=2016-01-01 --until=2017-01-01 +``` + +``` +⁴ Count commits in 2016 +``` + +``` +$ git log --oneline --since=2016-01-01 --until=2017-01-01 | wc -l +``` + +``` +⁵ ... and in 2015 +``` + +``` +$ git log --oneline --since=2015-01-01 --until=2016-01-01 | wc -l +``` + +``` +⁶ Net LOC added/removed in 2016 +``` + +``` +$ git diff --shortstat `git rev-list -1 --until=2016-01-01 master` \ + `git rev-list -1 --until=2017-01-01 master` +``` + +以上的命令是在 Git 的 `master` 分支运行的,所以不会显示其他出色的分支上没有合并的工作。如果你使用这些命令,请记住提交的数量和代码行数不是应该值得信赖的度量方式。请不要使用它们来衡量你的团队成员的贡献。 + +现在,让我们开始说好的回顾…… + +### 完成 Git worktress +`git worktree` 命令首次出现于 Git v2.5 但是在 2016 年有了一些显著的增强。两个有价值的新特性在 v2.7 被引入—— `list` 子命令,和为二分搜索增加了命令空间的 refs——而 `lock`/`unlock` 子命令则是在 v2.10被引入。 + +#### 什么是 worktree 呢? +`[git worktree][49]` 命令允许你同步地检出和操作处于不同路径下的同一仓库的多个分支。例如,假如你需要做一次快速的修复工作但又不想扰乱你当前的工作区,你可以使用以下命令在一个新路径下检出一个新分支 +``` +$ git worktree add -b hotfix/BB-1234 ../hotfix/BB-1234 +Preparing ../hotfix/BB-1234 (identifier BB-1234) +HEAD is now at 886e0ba Merged in bedwards/BB-13430-api-merge-pr (pull request #7822) +``` + +Worktree 不仅仅是为分支工作。你可以检出多个里程碑(tags)作为不同的工作树来并行构建或测试它们。例如,我从 Git v2.6 和 v2.7 的里程碑中创建工作树来检验不同版本 Git 的行为特征。 + +``` +$ git worktree add ../git-v2.6.0 v2.6.0 +Preparing ../git-v2.6.0 (identifier git-v2.6.0) +HEAD is now at be08dee Git 2.6 +``` + +``` +$ git worktree add ../git-v2.7.0 v2.7.0 +Preparing ../git-v2.7.0 (identifier git-v2.7.0) +HEAD is now at 7548842 Git 2.7 +``` + +``` +$ git worktree list +/Users/kannonboy/src/git 7548842 [master] +/Users/kannonboy/src/git-v2.6.0 be08dee (detached HEAD) +/Users/kannonboy/src/git-v2.7.0 7548842 (detached HEAD) +``` + +``` +$ cd ../git-v2.7.0 && make +``` + +你也使用同样的技术来并行构造和运行你自己应用程序的不同版本。 + +#### 列出工作树 + +`git worktree list` 子命令(于 Git v2.7引入)显示所有与当前仓库有关的工作树。 + +``` +$ git worktree list +/Users/kannonboy/src/bitbucket/bitbucket 37732bd [master] +/Users/kannonboy/src/bitbucket/staging d5924bc [staging] +/Users/kannonboy/src/bitbucket/hotfix-1234 37732bd [hotfix/1234] +``` + +#### 二分查找工作树 + +`[gitbisect][50]` 是一个简洁的 Git 命令,可以让我们对提交记录执行一次二分搜索。通常用来找到哪一次提交引入了一个指定的退化。例如,如果在我的 `master` 分支最后的提交上有一个测试没有通过,我可以使用 `git bisect` 来贯穿仓库的历史来找寻第一次造成这个错误的提交。 + +``` +$ git bisect start +``` + +``` +# indicate the last commit known to be passing the tests +# (e.g. the latest release tag) +$ git bisect good v2.0.0 +``` + +``` +# indicate a known broken commit (e.g. the tip of master) +$ git bisect bad master +``` + +``` +# tell git bisect a script/command to run; git bisect will +# find the oldest commit between "good" and "bad" that causes +# this script to exit with a non-zero status +$ git bisect run npm test +``` + +在后台,bisect 使用 refs 来跟踪 好 与 坏 的提交来作为二分搜索范围的上下界限。不幸的是,对工作树的粉丝来说,这些 refs 都存储在寻常的 `.git/refs/bisect` 命名空间,意味着 `git bisect` 操作如果运行在不同的工作树下可能会互相干扰。 +到了 v2.7 版本,bisect 的 refs 移到了 `.git/worktrees/$worktree_name/refs/bisect`, 所以你可以并行运行 bisect 操作于多个工作树中。 + +#### 锁定工作树 +当你完成了一颗工作树的工作,你可以直接删除它,然后通过运行 `git worktree prune` 等它被当做垃圾自动回收。但是,如果你在网络共享或者可移除媒介上存储了一颗工作树,如果工作树目录在删除期间不可访问,工作树会被完全清除——不管你喜不喜欢!Git v2.10 引入了 `git worktree lock` 和 `unlock` 子命令来防止这种情况发生。 +``` +# to lock the git-v2.7 worktree on my USB drive +$ git worktree lock /Volumes/Flash_Gordon/git-v2.7 --reason \ +"In case I remove my removable media" +``` + +``` +# to unlock (and delete) the worktree when I'm finished with it +$ git worktree unlock /Volumes/Flash_Gordon/git-v2.7 +$ rm -rf /Volumes/Flash_Gordon/git-v2.7 +$ git worktree prune +``` + +`--reason` 标签允许为未来的你留一个记号,描述为什么当初工作树被锁定。`git worktree unlock` 和 `lock` 都要求你指定工作树的路径。或者,你可以 `cd` 到工作树目录然后运行 `git worktree lock .` 来达到同样的效果。 + + + +### 更多 Git `reabse` 选项 +2016 年三月,Git v2.8 增加了在拉取过程中交互进行 rebase 的命令 `git pull --rebase=interactive` 。对应地,六月份 Git v2.9 发布了通过 `git rebase -x` 命令对执行变基操作而不需要进入交互模式的支持。 + +#### Re-啥? + +在我们继续深入前,我假设读者中有些并不是很熟悉或者没有完全习惯变基命令或者交互式变基。从概念上说,它很简单,但是与很多 Git 的强大特性一样,变基散发着听起来很复杂的专业术语的气息。所以,在我们深入前,先来快速的复习一下什么是 rebase。 + +变基操作意味着将一个或多个提交在一个指定分支上重写。`git rebase` 命令是被深度重载了,但是 rebase 名字的来源事实上还是它经常被用来改变一个分支的基准提交(你基于此提交创建了这个分支)。 + +从概念上说,rebase 通过将你的分支上的提交存储为一系列补丁包临时释放了它们,接着将这些补丁包按顺序依次打在目标提交之上。 + + ![](https://cdn-images-1.medium.com/max/800/1*mgyl38slmqmcE4STS56nXA.gif) + +对 master 分支的一个功能分支执行变基操作 (`git reabse master`)是一种通过将 master 分支上最新的改变合并到功能分支的“保鲜法”。对于长期存在的功能分支,规律的变基操作能够最大程度的减少开发过程中出现冲突的可能性和严重性。 + +有些团队会选择在合并他们的改动到 master 前立即执行变基操作以实现一次快速合并 (`git merge --ff `)。对 master 分支快速合并你的提交是通过简单的将 master ref 指向你的重写分支的顶点而不需要创建一个合并提交。 + + ![](https://cdn-images-1.medium.com/max/800/1*QXa3znQiuNWDjxroX628VA.gif) + +变基是如此方便和功能强大以致于它已经被嵌入其他常见的 Git 命令中,例如 `git pull`。如果你在本地 master 分支有未推送的提交,运行 `git pull` 命令从 origin 拉取你队友的改动会造成不必要的合并提交。 + + ![](https://cdn-images-1.medium.com/max/800/1*IxDdJ5CygvSWdD8MCNpZNg.gif) + +这有点混乱,而且在繁忙的团队,你会获得成堆的不必要的合并提交。`git pull --rebase` 将你本地的提交在你队友的提交上执行变基而不产生一个合并提交。 + ![](https://cdn-images-1.medium.com/max/800/1*HcroDMwBE9m21-hOeIwRmw.gif) + +这很整洁吧!甚至更酷,Git v2.8 引入了一个新特性,允许你在拉取时 _交互地_ 变基。 + +#### 交互式变基 + +交互式变基是变基操作的一种更强大的形态。和标准变基操作相似,它可以重写提交,但它也可以向你提供一个机会让你能够交互式地修改这些将被重新运用在新基准上的提交。 + +当你运行 `git rebase --interactive` (或 `git pull --rebase=interactive`)时,你会在你的文本编辑器中得到一个可供选择的提交列表视图。 +``` +$ git rebase master --interactive +``` + +``` +pick 2fde787 ACE-1294: replaced miniamalCommit with string in test +pick ed93626 ACE-1294: removed pull request service from test +pick b02eb9a ACE-1294: moved fromHash, toHash and diffType to batch +pick e68f710 ACE-1294: added testing data to batch email file +``` + +``` +# Rebase f32fa9d..0ddde5f onto f32fa9d (4 commands) +# +# Commands: +# p, pick = use commit +# r, reword = use commit, but edit the commit message +# e, edit = use commit, but stop for amending +# s, squash = use commit, but meld into previous commit +# f, fixup = like "squash", but discard this commit's log message +# x, exec = run command (the rest of the line) using shell +# d, drop = remove commit +# +# These lines can be re-ordered; they are executed from top to +# bottom. +# +# If you remove a line here THAT COMMIT WILL BE LOST. +``` + +注意到每一条提交旁都有一个 `pick`。这是对 rebase 而言,"照原样留下这个提交"。如果你现在就退出文本编辑器,它会执行一次如上文所述的普通变基操作。但是,如果你将 `pick` 改为 `edit` 或者其他 rebase 命令中的一个,变基操作会允许你在它被重新运用前改变它。有效的变基命令有如下几种: +* `reword`: 编辑提交信息。 +* `edit`: 编辑提交了的文件。 +* `squash`: 将提交与之前的提交(同在文件中)合并,并将提交信息拼接。 +* `fixup`: 将本提交与上一条提交合并,并且逐字使用上一条提交的提交信息(这很方便,如果你为一个很小的改动创建了第二个提交,而它本身就应该属于上一条提交,例如,你忘记暂存了一个文件)。 +* `exec`: 运行一条任意的 shell 命令(我们将会在下一节看到本例一次简洁的使用场景)。 +* `drop`: 这将丢弃这条提交。 + +你也可以在文件内重新整理提交,这样会改变他们被重新运用的顺序。这会很顺手当你对不同的主题创建了交错的提交时,你可以使用 `squash` 或者 `fixup` 来将其合并成符合逻辑的原子提交。 + +当你设置完命令并且保存这个文件后,Git 将递归每一条提交,在每个 `reword` 和 `edit` 命令处为你暂停来执行你设计好的改变并且自动运行 `squash`, `fixup`,`exec` 和 `drop`命令。 + +####非交互性式执行 +当你执行变基操作时,本质上你是在通过将你每一条新提交应用于指定基址的头部来重写历史。`git pull --rebase` 可能会有一点危险,因为根据上游分支改动的事实,你的新建历史可能会由于特定的提交遭遇测试失败甚至编译问题。如果这些改动引起了合并冲突,变基过程将会暂停并且允许你来解决它们。但是,整洁的合并改动仍然有可能打断编译或测试过程,留下破败的提交弄乱你的提交历史。 + +但是,你可以指导 Git 为每一个重写的提交来运行你的项目测试套件。在 Git v2.9 之前,你可以通过绑定 `git rebase --interactive` 和 `exec` 命令来实现。例如这样: +``` +$ git rebase master −−interactive −−exec=”npm test” +``` + +...会生成在重写每条提交后执行 `npm test` 这样的一个交互式变基计划,保证你的测试仍然会通过: + +``` +pick 2fde787 ACE-1294: replaced miniamalCommit with string in test +exec npm test +pick ed93626 ACE-1294: removed pull request service from test +exec npm test +pick b02eb9a ACE-1294: moved fromHash, toHash and diffType to batch +exec npm test +pick e68f710 ACE-1294: added testing data to batch email file +exec npm test +``` + +``` +# Rebase f32fa9d..0ddde5f onto f32fa9d (4 command(s)) +``` + +如果出现了测试失败的情况,变基会暂停并让你修复这些测试(并且将你的修改应用于相应提交): +``` +291 passing +1 failing +``` + +``` +1) Host request “after all” hook: +Uncaught Error: connect ECONNRESET 127.0.0.1:3001 +… +npm ERR! Test failed. +Execution failed: npm test +You can fix the problem, and then run + git rebase −−continue +``` + +这很方便,但是使用交互式变基有一点臃肿。到了 Git v2.9,你可以这样来实现非交互式变基: +``` +$ git rebase master -x “npm test” +``` + +简单替换 `npm test` 为 `make`,`rake`,`mvn clean install`,或者任何你用来构建或测试你的项目的命令。 + +####小小警告 +就像电影里一样,重写历史可是一个危险的行当。任何提交被重写为变基操作的一部分都将改变它的 SHA-1 ID,这意味着 Git 会把它当作一个全新的提交对待。如果重写的历史和原来的历史混杂,你将获得重复的提交,而这可能在你的团队中引起不少的疑惑。 + +为了避免这个问题,你仅仅需要遵照一条简单的规则: +> _永远不要变基一条你已经推送的提交!_ + +坚持这一点你会没事的。 + + + +### `Git LFS` 的性能提升 +[Git 是一个分布式版本控制系统][64],意味着整个仓库的历史会在克隆阶段被传送到客户端。对包含大文件的项目——尤其是大文件经常被修改——初始克隆会非常耗时,因为每一个版本的每一个文件都必须下载到客户端。[Git LFS(Large File Storage 大文件存储)][65] 是一个 Git 拓展包,由 Atlassian,GitHub 和其他一些开源贡献者开发,通过消极地下载大文件的相对版本来减少仓库中大文件的影响。更明确地说,大文件是在检出过程中按需下载的而不是在克隆或抓取过程中。 + +在 Git 2016 年的五大发布中,Git LFS 自身有四个功能丰富的发布:v1.2 到 v1.5。你可以凭 Git LFS 自身来写一系列回顾文章,但是就这篇文章而言,我将专注于 2016 年解决的一项最重要的主题:速度。一系列针对 Git 和 Git LFS 的改进极大程度地优化了将文件传入/传出服务器的性能。 + +#### 长期过滤进程 + +当你 `git add` 一个文件时,Git 的净化过滤系统会被用来在文件被写入 Git 目标存储前转化文件的内容。Git LFS 通过使用净化过滤器将大文件内容存储到 LFS 缓存中以缩减仓库的大小,并且增加一个小“指针”文件到 Git 目标存储中作为替代。 + + + ![](https://cdn-images-1.medium.com/max/800/0*Ku328eca7GLOo7sS.png) + +污化过滤器是净化过滤器的对立面——正如其名。在 `git checkout` 过程中从一个 Git 目标仓库读取文件内容时,污化过滤系统有机会在文件被写入用户的工作区前将其改写。Git LFS 污化过滤器通过将指针文件替代为对应的大文件将其转化,可以是从 LFS 缓存中获得或者通过读取存储在 Bitbucket 的 Git LFS。 + +![](https://cdn-images-1.medium.com/max/800/0*CU60meE1lbCuivn7.png) + +传统上,污化和净化过滤进程在每个文件被增加和检出时只能被唤起一次。所以,一个项目如果有 1000 个文件在被 Git LFS 追踪 ,做一次全新的检出需要唤起 `git-lfs-smudge` 命令 1000 次。尽管单次操作相对很迅速,但是经常执行 1000 次独立的污化进程总耗费惊人。、 + +针对 Git v2.11(和 Git LFS v1.5),污化和净化过滤器可以被定义为长期进程,为第一个需要过滤的文件调用一次,然后为之后的文件持续提供污化或净化过滤直到父 Git 操作结束。[Lars Schneider][66],Git 的长期过滤系统的贡献者,简洁地总结了对 Git LFS 性能改变带来的影响。 +> 使用 12k 个文件的测试仓库的过滤进程在 macOS 上快了80 倍,在 Windows 上 快了 58 倍。在 Windows 上,这意味着测试运行了 57 秒而不是 55 分钟。 +> 这真是一个让人印象深刻的性能增强! + +#### LFS 专有克隆 + +长期运行的污化和净化过滤器在对向本地缓存读写的加速做了很多贡献,但是对大目标传入/传出 Git LFS 服务器的速度提升贡献很少。 每次 Git LFS 污化过滤器在本地 LFS 缓存中无法找到一个文件时,它不得不使用两个 HTTP 请求来获得该文件:一个用来定位文件,另外一个用来下载它。在一次 `git clone` 过程中,你的本地 LFS 缓存是空的,所以 Git LFS 会天真地为你的仓库中每个 LFS 所追踪的文件创建两个 HTTP 请求: + + ![](https://cdn-images-1.medium.com/max/800/0*ViL7r3ZhkGvF0z3-.png) + +幸运的是,Git LFS v1.2 提供了专门的 `[git lfs clone][51]` 命令。不再是一次下载一个文件; `git lfs clone` 禁止 Git LFS 污化过滤器,等待检出结束,然后从 Git LFS 存储中按批下载任何需要的文件。这允许了并行下载并且将需要的 HTTP 请求数量减半。 + + ![](https://cdn-images-1.medium.com/max/800/0*T43VA0DYTujDNgkH.png) + +###自定义传输路由器 + +正如之前讨论过的,Git LFS 在 v1.5 中 发起了对长期过滤进程的支持。不过,对另外一种可插入进程的支持早在今年年初就发布了。 Git LFS 1.3 包含了对可插拔传输路由器的支持,因此不同的 Git LFS 托管服务可以定义属于它们自己的协议来向或从 LFS 存储中传输文件。 + +直到 2016 年底,Bitbucket 是唯一一个执行专属 Git LFS 传输协议 [Bitbucket LFS Media Adapter][67] 的托管服务商。这是为了从 Bitbucket 的一个独特的被称为 chunking 的 LFS 存储 API 特性中获利。Chunking 意味着在上传或下载过程中,大文件被分解成 4MB 的文件块(chunk)。 + ![](https://cdn-images-1.medium.com/max/800/1*N3SpjQZQ1Ge8OwvWrtS1og.gif) + +分块给予了 Bitbucket 支持的 Git LFS 三大优势: +1. 并行下载与上传。默认地,Git LFS 最多并行传输三个文件。但是,如果只有一个文件被单独传输(这也是 Git LFS 污化过滤器的默认行为),它会在一个单独的流中被传输。Bitbucket 的分块允许同一文件的多个文件块同时被上传或下载,经常能够梦幻地提升传输速度。 +2. 可恢复文件块传输。文件块都在本地缓存,所以如果你的下载或上传被打断,Bitbucket 的自定义 LFS 流媒体路由器会在下一次你推送或拉取时仅为丢失的文件块恢复传输。 +3. 免重复。Git LFS,正如 Git 本身,是内容索位;每一个 LFS 文件都由它的内容生成的 SHA-256 哈希值认证。所以,哪怕你稍微修改了一位数据,整个文件的 SHA-256 就会修改而你不得不重新上传整个文件。分块允许你仅仅重新上传文件真正被修改的部分。举个例子,想想一下Git LFS 在追踪一个 41M 的电子游戏精灵表。如果我们增加在此精灵表上增加 2MB 的新层并且提交它,传统上我们需要推送整个新的 43M 文件到服务器端。但是,使用 Bitbucket 的自定义传输路由,我们仅仅需要推送 ~7MB:先是 4MB 文件块(因为文件的信息头会改变)和我们刚刚添加的包含新层的 3MB 文件块!其余未改变的文件块在上传过程中被自动跳过,节省了巨大的带宽和时间消耗。 + +可自定义的传输路由器是 Git LFS 一个伟大的特性,它们使得不同服务商在不过载核心项目的前提下体验适合其服务器的优化后的传输协议。 + +### 更佳的 `git diff` 算法与默认值 + +不像其他的版本控制系统,Git 不会明确地存储文件被重命名了的事实。例如,如果我编辑了一个简单的 Node.js 应用并且将 `index.js` 重命名为 `app.js`,然后运行 `git diff`,我会得到一个看起来像一个文件被删除另一个文件被新建的结果。 + + ![](https://cdn-images-1.medium.com/max/800/1*ohMUBpSh_jqz2ffScJ7ApQ.png) + +我猜测移动或重命名一个文件从技术上来讲是一次删除后跟一次新建,但这不是对人类最友好的方式来诉说它。其实,你可以使用 `-M` 标志来指示 Git 在计算差异时抽空尝试检测重命名文件。对之前的例子,`git diff -M` 给我们如下结果: + ![](https://cdn-images-1.medium.com/max/800/1*ywYjxBc1wii5O8EhHbpCTA.png) + +第二行显示的 similarity index 告诉我们文件内容经过比较后的相似程度。默认地,`-M` 会考虑任意两个文件都有超过 50% 相似度。这意味着,你需要编辑少于 50% 的行数来确保它们被识别成一个重命名后的文件。你可以通过加上一个百分比来选择你自己的 similarity index,如,`-M80%`。 + +到 Git v2.9 版本,如果你使用了 `-M` 标志 `git diff` 和 `git log` 命令都会默认检测重命名。如果不喜欢这种行为(或者,更现实的情况,你在通过一个脚本来解析 diff 输出),那么你可以通过显示的传递 `--no-renames` 标志来禁用它。 + +#### 详细的提交 + +你经历过调用 `git commit` 然后盯着空白的 shell 试图想起你刚刚做过的所有改动吗?verbose 标志就为此而来! + +不像这样: +``` +Ah crap, which dependency did I just rev? +``` + +``` +# Please enter the commit message for your changes. Lines starting +# with ‘#’ will be ignored, and an empty message aborts the commit. +# On branch master +# Your branch is up-to-date with ‘origin/master’. +# +# Changes to be committed: +# new file: package.json +# +``` + +...你可以调用 `git commit --verbose` 来查看你改动造成的内联差异。不用担心,这不会包含在你的提交信息中: + + ![](https://cdn-images-1.medium.com/max/800/1*1vOYE2ow3ZDS8BP_QfssQw.png) + +`--verbose` 标志不是最新的,但是直到 Git v2.9 你可以通过 `git config --global commit.verbose true` 永久的启用它。 + +#### 实验性的 Diff 改进 + +当一个被修改部分前后几行相同时,`git diff` 可能产生一些稍微令人迷惑的输出。如果在一个文件中有两个或者更多相似结构的函数时这可能发生。来看一个有些刻意人为的例子,想象我们有一个 JS 文件包含一个单独的函数: +``` +/* @return {string} "Bitbucket" */ +function productName() { + return "Bitbucket"; +} +``` + +现在想象一下我们刚提交的改动包含一个预谋的 _另一个_可以做相似事情的函数: +``` +/* @return {string} "Bitbucket" */ +function productId() { + return "Bitbucket"; +} +``` + +``` +/* @return {string} "Bitbucket" */ +function productName() { + return "Bitbucket"; +} +``` + +我们希望 `git diff` 显示开头五行被新增,但是实际上它不恰当地将最初提交的第一行也包含进来。 + + ![](https://cdn-images-1.medium.com/max/800/1*9C7DWMObGHMEqD-QFGHmew.png) + +错误的注释被包含在了 diff 中!这虽不是世界末日,但每次发生这种事情总免不了花费几秒钟的意识去想 _啊?_ +在十二月,Git v2.11 介绍了一个新的实验性的 diff 选项,`--indent-heuristic`,尝试生成从美学角度来看更赏心悦目的 diff。 + + ![](https://cdn-images-1.medium.com/max/800/1*UyWZ6JjC-izDquyWCA4bow.png) + +在后台,`--indent-heuristic` 在每一次改动造成的所有可能的 diff 中循环,并为它们分别打上一个 "不良" 分数。这是基于试探性的如差异文件块是否以不同等级的缩进开始和结束(从美学角度讲不良)以及差异文件块前后是否有空白行(从美学角度讲令人愉悦)。最后,有着最低不良分数的块就是最终输出。 + +这个特性还是实验性的,但是你可以通过应用 `--indent-heuristic` 选项到任何 `git diff` 命令来专门测试它。如果,如果你喜欢在刀口上讨生活,你可以这样将其在你的整个系统内使能: +``` +$ git config --global diff.indentHeuristic true +``` + +### Submodules 差强人意 + +子模块允许你从 Git 仓库内部引用和包含其他 Git 仓库。这通常被用在当一些项目管理的源依赖也在被 Git 跟踪时,或者被某些公司用来作为包含一系列相关项目的 [monorepo][68] 的替代品。 + +由于某些用法的复杂性以及使用错误的命令相当容易破坏它们的事实,Submodule 得到了一些坏名声。 + + ![](https://cdn-images-1.medium.com/max/800/1*xNffiElY7BZNMDM0jm0JNQ.gif) + +但是,它们还是有着它们的用处,而且,我想,仍然对其他方案有依赖时的最好的选择。 幸运的是,2016 对 submodule 用户来说是伟大的一年,在几次发布中落地了许多意义重大的性能和特性提升。 + +#### 并行抓取 +当克隆或则抓取一个仓库时,加上 `--recurse-submodules` 选项意味着任何引用的 submodule 也将被克隆或更新。传统上,这会被串行执行,每次只抓取一个 submodule。直到 Git v2.8,你可以附加 `--jobs=n` 选项来使用 _n_ 个并行线程来抓取 submodules。 + +我推荐永久的配置这个选项: + +``` +$ git config --global submodule.fetchJobs 4 +``` + +...或者你可以选择使用任意程度的平行化。 + +#### 浅层子模块 +Git v2.9 介绍了 `git clone —shallow-submodules` 标志。它允许你抓取你仓库的完整克隆,然后递归的浅层克隆所有引用的子模块的一个提交。如果你不需要项目的依赖的完整记录时会很有用。 + +例如,一个仓库有着一些混合了的子模块,其中包含有其他方案商提供的依赖和你自己其它的项目。你可能希望初始化时执行浅层子模块克隆然后深度选择几个你想要与之工作的项目。 + +另一种情况可能是配置一次持续性的集成或调度工作。Git 需要超级仓库以及每个子模块最新的提交以便能够真正执行构建。但是,你可能并不需要每个子模块全部的历史记录,所以仅仅检索最新的提交可以为你省下时间和带宽。 + +#### 子模块的替代品 + +`--reference` 选项可以和 `git clone` 配合使用来指定另一个本地仓库作为一个目标存储来保存你本地已经存在的又通过网络传输的重复制目标。语法为: + +``` +$ git clone --reference +``` + +直到 Git v2.11,你可以使用 `—reference` 选项与 `—recurse-submodules` 结合来设置子模块替代品从另一个本地仓库指向子模块。其语法为: + +``` +$ git clone --recurse-submodules --reference +``` + +这潜在的可以省下很大数量的带宽和本地磁盘空间,但是如果引用的本地仓库不包含你所克隆自的远程仓库所必需的所有子模块时,它可能会失败。。 + +幸运的是,方便的 `—-reference-if-able` 选项将会让它优雅地失败,然后为丢失了的被引用的本地仓库的所有子模块回退为一次普通的克隆。 + +``` +$ git clone --recurse-submodules --reference-if-able \ + +``` + +#### 子模块的 diff + +在 Git v2.11 之前,Git 有两种模式来显示对更新了仓库子模块的提交之间的差异。 + +`git diff —-submodule=short` 显示你的项目引用的子模块中的旧提交和新提交( 这也是如果你整体忽略 `--submodule` 选项的默认结果): + + ![](https://cdn-images-1.medium.com/max/800/1*K71cJ30NokO5B69-a470NA.png) + +`git diff —submodule=log` 有一点啰嗦,显示更新了的子模块中任意新建或移除的提交的信息中统计行。 + + ![](https://cdn-images-1.medium.com/max/800/1*frvsd_T44De8_q0uvNHB1g.png) + +Git v2.11 引入了第三个更有用的选项:`—-submodule=diff`。这会显示更新后的子模块所有改动的完整的 diff。 + + ![](https://cdn-images-1.medium.com/max/800/1*nPhJTjP8tcJ0cD8s3YOmjw.png) + +### `git stash` 的 90 个增强 + +不像 submodules,几乎没有 Git 用户不钟爱 `[git stash][52]`。 `git stash` 临时搁置(或者 _藏匿_)你对工作区所做的改动使你能够先处理其他事情,结束后重新将搁置的改动恢复到先前状态。 + +#### 自动搁置 + +如果你是 `git rebase` 的粉丝,你可能很熟悉 `--autostash` 选项。它会在变基之前自动搁置工作区所有本地修改然后等变基结束再将其复用。 +``` +$ git rebase master --autostash +Created autostash: 54f212a +HEAD is now at 8303dca It's a kludge, but put the tuple from the database in the cache. +First, rewinding head to replay your work on top of it... +Applied autostash. +``` + +这很方便,因为它使得你可以在一个不洁的工作区执行变基。有一个方便的配置标志叫做 `rebase.autostash` 可以将这个特性设为默认,你可以这样来全局使能它: +``` +$ git config --global rebase.autostash true +``` + +`rebase.autostash` 实际上自从 [Git v1.8.4][69] 就可用了,但是 v2.7 引入了通过 `--no-autostash` 选项来取消这个标志的功能。如果你对未暂存的改动使用这个选项,变基会被一条工作树被污染的警告禁止: +``` +$ git rebase master --no-autostash +Cannot rebase: You have unstaged changes. +Please commit or stash them. +``` + +#### 补丁式搁置 + +说到配置标签,Git v2.7 也引入了 `stash.showPatch`。`git stash show` 的默认行为是显示你搁置文件的汇总。 +``` +$ git stash show +package.json | 2 +- +1 file changed, 1 insertion(+), 1 deletion(-) +``` + +将 `-p` 标志传入会将 `git stash show` 变为 "补丁模式",这将会显示完整的 diff: + ![](https://cdn-images-1.medium.com/max/800/1*HpcT3quuKKQj9CneqPuufw.png) + +`stash.showPatch` 将这个行为定为默认。你可以将其全局使能: +``` +$ git config --global stash.showPatch true +``` + +如果你使能 `stash.showPatch` 但却之后决定你仅仅想要查看文件总结,你可以通过传入 `--stat` 选项来重新获得之前的行为。 +``` +$ git stash show --stat +package.json | 2 +- +1 file changed, 1 insertion(+), 1 deletion(-) +``` + +顺便一提:`--no-patch` 是一个有效选项但它不会如你所希望的改写 `stash.showPatch` 的结果。不仅如此,它会传递给用来生成补丁时潜在调用的 `git diff` 命令,然后你会发现完全没有任何输出。 + +#### 简单的搁置标识 +如果你是 `git stash` 的粉丝,你可能知道你可以搁置多次改动然后通过 `git stash list` 来查看它们: +``` +$ git stash list +stash@{0}: On master: crazy idea that might work one day +stash@{1}: On master: desperate samurai refactor; don't apply +stash@{2}: On master: perf improvement that I forgot I stashed +stash@{3}: On master: pop this when we use Docker in production +``` + +但是,你可能不知道为什么 Git 的搁置有着这么难以理解的标识(`stash@{1}`, `stash@{2}`, 等)也可能将它们勾勒成 "仅仅是 Git 的一个特性吧"。实际上就像很多 Git 特性一样,这些奇怪的标志实际上是 Git 数据模型一个非常巧妙使用(或者说是滥用了的)的特性。 + +在后台,`git stash` 命令实际创建了一系列特别的提交目标,这些目标对你搁置的改动做了编码并且维护一个 [reglog][70] 来保存对这些特殊提交的参考。 这也是为什么 `git stash list` 的输出看起来很像 `git reflog` 的输出。当你运行 `git stash apply stash@{1}` 时,你实际上在说,"从stash reflog 的位置 1 上应用这条提交 " + +直到 Git v2.11,你不再需要使用完整的 `stash@{n}` 语句。相反,你可以通过一个简单的整数指出搁置在 stash reflog 中的位置来引用它们。 + +``` +$ git stash show 1 +$ git stash apply 1 +$ git stash pop 1 +``` + +讲了很多了。如果你还想要多学一些搁置是怎么保存的,我在 [这篇教程][71] 中写了一点这方面的内容。 +### <2016> <2017> +好了,结束了。感谢您的阅读!我希望您享受阅读这份长篇大论,正如我享受在 Git 的源码,发布文档,和 `man` 手册中探险一番来撰写它。如果你认为我忘记了一些重要的事,请留下一条评论或者在 [Twitter][72] 上让我知道,我会努力写一份后续篇章。 + +至于 Git 接下来会发生什么,这要靠广大维护者和贡献者了(其中有可能就是你!)。随着日益增长的采用,我猜测简化,改进后的用户体验,和更好的默认结果将会是 2017 年 Git 主要的主题。随着 Git 仓库变得又大又旧,我猜我们也可以看到继续持续关注性能和对大文件、深度树和长历史的改进处理。 + +如果你关注 Git 并且很期待能够和一些项目背后的开发者会面,请考虑来 Brussels 花几周时间来参加 [Git Merge][74] 。我会在[那里发言][75]!但是更重要的是,很多维护 Git 的开发者将会出席这次会议而且一年一度的 Git 贡献者峰会很可能会指定来年发展的方向。 + +或者如果你实在等不及,想要获得更多的技巧和指南来改进你的工作流,请参看这份 Atlassian 的优秀作品: [Git 教程][76] 。 + + +*如果你翻到最下方来找第一节的脚注,请跳转到 [ [引用是需要的] ][77]一节去找生成统计信息的命令。免费的封面图片是由 [ instaco.de ][78] 生成的 ❤️。* + +-------------------------------------------------------------------------------- + +via: https://hackernoon.com/git-in-2016-fad96ae22a15#.t5c5cm48f + +作者:[Tim Pettersen][a] +译者:[xiaow6](https://github.com/xiaow6) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://hackernoon.com/@kannonboy?source=post_header_lockup +[1]:https://medium.com/@g.kylafas/the-git-config-command-is-missing-a-yes-at-the-end-as-in-git-config-global-commit-verbose-yes-7e126365750e?source=responses---------1---------- +[2]:https://medium.com/@kannonboy/thanks-giorgos-fixed-f3b83c61589a?source=responses---------1---------- +[3]:https://medium.com/@TomSwirly/i-read-the-whole-thing-from-start-to-finish-415a55d89229?source=responses---------0-31--------- +[4]:https://medium.com/@g.kylafas +[5]:https://medium.com/@g.kylafas?source=responses---------1---------- +[6]:https://medium.com/@kannonboy +[7]:https://medium.com/@kannonboy?source=responses---------1---------- +[8]:https://medium.com/@TomSwirly +[9]:https://medium.com/@TomSwirly?source=responses---------0-31--------- +[10]:https://medium.com/@g.kylafas/the-git-config-command-is-missing-a-yes-at-the-end-as-in-git-config-global-commit-verbose-yes-7e126365750e?source=responses---------1----------#--responses +[11]:https://hackernoon.com/@kannonboy +[12]:https://hackernoon.com/@kannonboy?source=placement_card_footer_grid---------0-44 +[13]:https://medium.freecodecamp.com/@BillSourour +[14]:https://medium.freecodecamp.com/@BillSourour?source=placement_card_footer_grid---------1-43 +[15]:https://blog.uncommon.is/@lut4rp +[16]:https://blog.uncommon.is/@lut4rp?source=placement_card_footer_grid---------2-43 +[17]:https://medium.com/@kannonboy +[18]:https://medium.com/@kannonboy +[19]:https://medium.com/@g.kylafas/the-git-config-command-is-missing-a-yes-at-the-end-as-in-git-config-global-commit-verbose-yes-7e126365750e?source=responses---------1---------- +[20]:https://medium.com/@kannonboy/thanks-giorgos-fixed-f3b83c61589a?source=responses---------1---------- +[21]:https://medium.com/@TomSwirly/i-read-the-whole-thing-from-start-to-finish-415a55d89229?source=responses---------0-31--------- +[22]:https://hackernoon.com/setting-breakpoints-on-a-snowy-evening-df34fc3168e2?source=placement_card_footer_grid---------0-44 +[23]:https://medium.freecodecamp.com/the-code-im-still-ashamed-of-e4c021dff55e?source=placement_card_footer_grid---------1-43 +[24]:https://blog.uncommon.is/using-git-to-generate-versionname-and-versioncode-for-android-apps-aaa9fc2c96af?source=placement_card_footer_grid---------2-43 +[25]:https://hackernoon.com/git-in-2016-fad96ae22a15#fd10 +[26]:https://hackernoon.com/git-in-2016-fad96ae22a15#cc52 +[27]:https://hackernoon.com/git-in-2016-fad96ae22a15#42b9 +[28]:https://hackernoon.com/git-in-2016-fad96ae22a15#4208 +[29]:https://hackernoon.com/git-in-2016-fad96ae22a15#a5c3 +[30]:https://hackernoon.com/git-in-2016-fad96ae22a15#c230 +[31]:https://hackernoon.com/tagged/git?source=post +[32]:https://hackernoon.com/tagged/web-development?source=post +[33]:https://hackernoon.com/tagged/software-development?source=post +[34]:https://hackernoon.com/tagged/programming?source=post +[35]:https://hackernoon.com/tagged/atlassian?source=post +[36]:https://hackernoon.com/@kannonboy +[37]:https://hackernoon.com/?source=footer_card +[38]:https://hackernoon.com/setting-breakpoints-on-a-snowy-evening-df34fc3168e2?source=placement_card_footer_grid---------0-44 +[39]:https://medium.freecodecamp.com/the-code-im-still-ashamed-of-e4c021dff55e?source=placement_card_footer_grid---------1-43 +[40]:https://blog.uncommon.is/using-git-to-generate-versionname-and-versioncode-for-android-apps-aaa9fc2c96af?source=placement_card_footer_grid---------2-43 +[41]:https://hackernoon.com/git-in-2016-fad96ae22a15#fd10 +[42]:https://hackernoon.com/git-in-2016-fad96ae22a15#fd10 +[43]:https://hackernoon.com/git-in-2016-fad96ae22a15#cc52 +[44]:https://hackernoon.com/git-in-2016-fad96ae22a15#cc52 +[45]:https://hackernoon.com/git-in-2016-fad96ae22a15#42b9 +[46]:https://hackernoon.com/git-in-2016-fad96ae22a15#4208 +[47]:https://hackernoon.com/git-in-2016-fad96ae22a15#a5c3 +[48]:https://hackernoon.com/git-in-2016-fad96ae22a15#c230 +[49]:https://git-scm.com/docs/git-worktree +[50]:https://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git#Binary-Search +[51]:https://www.atlassian.com/git/tutorials/git-lfs/#speeding-up-clones +[52]:https://www.atlassian.com/git/tutorials/git-stash/ +[53]:https://hackernoon.com/@kannonboy?source=footer_card +[54]:https://hackernoon.com/?source=footer_card +[55]:https://hackernoon.com/@kannonboy?source=post_header_lockup +[56]:https://hackernoon.com/@kannonboy?source=post_header_lockup +[57]:https://hackernoon.com/git-in-2016-fad96ae22a15#c8e9 +[58]:https://hackernoon.com/git-in-2016-fad96ae22a15#408a +[59]:https://hackernoon.com/git-in-2016-fad96ae22a15#315b +[60]:https://hackernoon.com/git-in-2016-fad96ae22a15#dbfb +[61]:https://hackernoon.com/git-in-2016-fad96ae22a15#2220 +[62]:https://hackernoon.com/git-in-2016-fad96ae22a15#bc78 +[63]:https://www.atlassian.com/git/tutorials/install-git/ +[64]:https://www.atlassian.com/git/tutorials/what-is-git/ +[65]:https://www.atlassian.com/git/tutorials/git-lfs/ +[66]:https://twitter.com/kit3bus +[67]:https://confluence.atlassian.com/bitbucket/bitbucket-lfs-media-adapter-856699998.html +[68]:https://developer.atlassian.com/blog/2015/10/monorepos-in-git/ +[69]:https://blogs.atlassian.com/2013/08/what-you-need-to-know-about-the-new-git-1-8-4/ +[70]:https://www.atlassian.com/git/tutorials/refs-and-the-reflog/ +[71]:https://www.atlassian.com/git/tutorials/git-stash/#how-git-stash-works +[72]:https://twitter.com/kannonboy +[73]:https://git.kernel.org/cgit/git/git.git/tree/Documentation/SubmittingPatches +[74]:http://git-merge.com/ +[75]:http://git-merge.com/#git-aliases +[76]:https://www.atlassian.com/git/tutorials +[77]:https://hackernoon.com/git-in-2016-fad96ae22a15#87c4 +[78]:http://instaco.de/ +[79]:https://medium.com/@Medium/personalize-your-medium-experience-with-users-publications-tags-26a41ab1ee0c#.hx4zuv3mg +[80]:https://hackernoon.com/ From ef8857d4e6e2a833752323aa23712507be54946a Mon Sep 17 00:00:00 2001 From: Flynn Date: Sat, 15 Apr 2017 11:43:03 +0800 Subject: [PATCH 16/37] Translated --- ...b Based Linux Performance Monitoring Tool.md | 188 ----------------- ...esktop Sharing In Ubuntu and Linux Mint.md | 129 ------------ ...b Based Linux Performance Monitoring Tool.md | 189 ++++++++++++++++++ ...esktop Sharing In Ubuntu and Linux Mint.md | 128 ++++++++++++ 4 files changed, 317 insertions(+), 317 deletions(-) delete mode 100644 sources/tech/20170403 pyDash – A Web Based Linux Performance Monitoring Tool.md delete mode 100644 sources/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md create mode 100644 translated/tech/20170403 pyDash – A Web Based Linux Performance Monitoring Tool.md create mode 100644 translated/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md diff --git a/sources/tech/20170403 pyDash – A Web Based Linux Performance Monitoring Tool.md b/sources/tech/20170403 pyDash – A Web Based Linux Performance Monitoring Tool.md deleted file mode 100644 index 288a1a7bdb..0000000000 --- a/sources/tech/20170403 pyDash – A Web Based Linux Performance Monitoring Tool.md +++ /dev/null @@ -1,188 +0,0 @@ -ucasFL is Translating -pyDash – A Web Based Linux Performance Monitoring Tool -============================================================ - -pydash is a lightweight [web-based monitoring tool for Linux][1] written in Python and [Django][2] plus Chart.js. It has been tested and can run on the following mainstream Linux distributions: CentOS, Fedora, Ubuntu, Debian, Arch Linux, Raspbian as well as Pidora. - -You can use it to keep an eye on your Linux PC/server resources such as CPUs, RAM, network stats, processes including online users and more. The dashboard is developed entirely using Python libraries provided in the main Python distribution, therefore it has a few dependencies; you don’t need to install many packages or libraries to run it. - -In this article, we will show you how to install pydash to monitor Linux server performance. - -### How to Install pyDash in Linux System - -1. First install required packages: git and Python pip as follows: - -``` --------------- On Debian/Ubuntu -------------- -$ sudo apt-get install git python-pip --------------- On CentOS/RHEL -------------- -# yum install epel-release -# yum install git python-pip --------------- On Fedora 22+ -------------- -# dnf install git python-pip -``` - -2. If you have git and Python pip installed, next, install virtualenv which helps to deal with dependency issues for Python projects, as below: - -``` -# pip install virtualenv -OR -$ sudo pip install virtualenv -``` - -3. Now using git command, clone the pydash directory into your home directory like so: - -``` -# git clone https://github.com/k3oni/pydash.git -# cd pydash -``` - -4. Next, create a virtual environment for your project called pydashtest using the virtualenv command below. - -``` -$ virtualenv pydashtest #give a name for your virtual environment like pydashtest -``` -[ - ![Create Virtual Environment](http://www.tecmint.com/wp-content/uploads/2017/03/create-virtual-environment.png) -][3] - -Create Virtual Environment - -Important: Take note the virtual environment’s bin directory path highlighted in the screenshot above, yours could be different depending on where you cloned the pydash folder. - -5. Once you have created the virtual environment (pydashtest), you must activate it before using it as follows. - -``` -$ source /home/aaronkilik/pydash/pydashtest/bin/activate -``` -[ - ![Active Virtual Environment](http://www.tecmint.com/wp-content/uploads/2017/03/after-activating-virtualenv.png) -][4] - -Active Virtual Environment - -From the screenshot above, you’ll note that the PS1 prompt changes indicating that your virtual environment has been activated and is ready for use. - -6. Now install the pydash project requirements; if you are curious enough, view the contents of requirements.txt using the [cat command][5] and the install them using as shown below. - -``` -$ cat requirements.txt -$ pip install -r requirements.txt -``` - -7. Now move into the pydash directory containing settings.py or simple run the command below to open this file to change the SECRET_KEY to a custom value. - -``` -$ vi pydash/settings.py -``` -[ - ![Set Secret Key](http://www.tecmint.com/wp-content/uploads/2017/03/change-secret-key.png) -][6] - -Set Secret Key - -Save the file and exit. - -8. Afterward, run the django command below to create the project database and install Django’s auth system and create a project super user. - -``` -$ python manage.py syncdb -``` - -Answer the questions below according to your scenario: - -``` -Would you like to create one now? (yes/no): yes -Username (leave blank to use 'root'): admin -Email address: aaronkilik@gmail.com -Password: ########### -Password (again): ############ -``` -[ - ![Create Project Database](http://www.tecmint.com/wp-content/uploads/2017/03/python-manage.py-syncdb.png) -][7] - -Create Project Database - -9. At this point, all should be set, now run the following command to start the Django development server. - -``` -$ python manage.py runserver -``` - -10. Next, open your web browser and type the URL: http://127.0.0.1:8000/ to get the web dashboard login interface. Enter the super user name and password you created while creating the database and installing Django’s auth system in step 8 and click Sign In. - -[ - ![pyDash Login Interface](http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-web-login-interface.png) -][8] - -pyDash Login Interface - -11. Once you login into pydash main interface, you will get a section for monitoring general system info, CPU, memory and disk usage together with system load average. - -Simply scroll down to view more sections. - -[ - ![pyDash Server Performance Overview](http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Server-Performance-Overview.png) -][9] - -pyDash Server Performance Overview - -12. Next, screenshot of the pydash showing a section for keeping track of interfaces, IP addresses, Internet traffic, disk read/writes, online users and netstats. - -[ - ![pyDash Network Overview](http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Network-Overview.png) -][10] - -pyDash Network Overview - -13. Next is a screenshot of the pydash main interface showing a section to keep an eye on active processes on the system. - -[ - ![pyDash Active Linux Processes](http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Active-Linux-Processes.png) -][11] - -pyDash Active Linux Processes - -For more information, check out pydash on Github: [https://github.com/k3oni/pydash][12]. - -That’s it for now! In this article, we showed you how to setup and test the main features of pydash in Linux. Share any thoughts with us via the feedback section below and in case you know of any useful and similar tools out there, let us know as well in the comments. - --------------------------------------------------------------------------------- - - -作者简介: - -I am Ravi Saive, creator of TecMint. A Computer Geek and Linux Guru who loves to share tricks and tips on Internet. Most Of My Servers runs on Open Source Platform called Linux. Follow Me: [Twitter][00], [Facebook][01] and [Google+][02] - --------------------------------------------------------------------------------- - - -via: http://www.tecmint.com/pydash-a-web-based-linux-performance-monitoring-tool/ - -作者:[Ravi Saive ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://www.tecmint.com/author/admin/ -[00]:https://twitter.com/ravisaive -[01]:https://www.facebook.com/ravi.saive -[02]:https://plus.google.com/u/0/+RaviSaive - -[1]:http://www.tecmint.com/command-line-tools-to-monitor-linux-performance/ -[2]:http://www.tecmint.com/install-and-configure-django-web-framework-in-centos-debian-ubuntu/ -[3]:http://www.tecmint.com/wp-content/uploads/2017/03/create-virtual-environment.png -[4]:http://www.tecmint.com/wp-content/uploads/2017/03/after-activating-virtualenv.png -[5]:http://www.tecmint.com/13-basic-cat-command-examples-in-linux/ -[6]:http://www.tecmint.com/wp-content/uploads/2017/03/change-secret-key.png -[7]:http://www.tecmint.com/wp-content/uploads/2017/03/python-manage.py-syncdb.png -[8]:http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-web-login-interface.png -[9]:http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Server-Performance-Overview.png -[10]:http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Network-Overview.png -[11]:http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Active-Linux-Processes.png -[12]:https://github.com/k3oni/pydash -[13]:http://www.tecmint.com/author/admin/ -[14]:http://www.tecmint.com/10-useful-free-linux-ebooks-for-newbies-and-administrators/ -[15]:http://www.tecmint.com/free-linux-shell-scripting-books/ diff --git a/sources/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md b/sources/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md deleted file mode 100644 index 3daf11a5e1..0000000000 --- a/sources/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md +++ /dev/null @@ -1,129 +0,0 @@ -ucasFL is Translating -How To Enable Desktop Sharing In Ubuntu and Linux Mint -============================================================ - - -Desktop sharing refers to technologies that enable remote access and remote collaboration on a computer desktop via a graphical terminal emulator. Desktop sharing allows two or more Internet-enabled computer users to work on the same files from different locations. - -In this article, we will show you how to enable desktop sharing in Ubuntu and Linux Mint, with a few vital security features. - -### Enabling Desktop Sharing in Ubuntu and Linux Mint - -1. In the Ubuntu Dash or Linux Mint Menu, search for “desktop sharing” as shown in the following screenshot, once you get it, launch it. - -[ - ![Search for Desktop Sharing in Ubuntu](http://www.tecmint.com/wp-content/uploads/2017/03/search-for-desktop-sharing.png) -][1] - -Search for Desktop Sharing in Ubuntu - -2. Once you launch Desktop sharing, there are three categories of desktop sharing settings: sharing, security and notification settings. - -Under sharing, check the option “Allow others users to view your desktop” to enable desktop sharing. Optionally, you can also permit other users to remotely control your desktops by checking the option “Allow others users to control your desktop”. - -[ - ![Desktop Sharing Preferences](http://www.tecmint.com/wp-content/uploads/2017/03/desktop-sharing-settings-inte.png) -][2] - -Desktop Sharing Preferences - -3. Next in security section, you can choose to manually confirm each remote connection by checking the option “You must confirm each access to this computer”. - -Again, another useful security feature is creating a certain shared password using the option “Require user to enter this password”, that remote users must know and enter each time they want to access your desktop. - -4. Concerning notifications, you can keep an eye on remote connections by choosing to show the notification area icon each time there is a remote connection to your desktops by selecting “Only when someone is connected”. - -[ - ![Configure Desktop Sharing Set](http://www.tecmint.com/wp-content/uploads/2017/03/Configure-Desktop-Sharing-Set.png) -][3] - -Configure Desktop Sharing Set - -When you have set all the desktop sharing options, click Close. Now you have successfully permitted desktop sharing on your Ubuntu or Linux Mint desktop. - -### Testing Desktop Sharing in Ubuntu Remotely - -You can test to ensure that it’s working using a remote connection application. In this example, I will show you how some of the options we set above work. - -5. I will connect to my Ubuntu PC using VNC (Virtual Network Computing) protocol via [remmina remote connection application][4]. - -[ - ![Remmina Desktop Sharing Tool](http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Desktop-Sharing-Tool.png) -][5] - -Remmina Desktop Sharing Tool - -6. After clicking on Ubuntu PC item, I get the interface below to configure my connection settings. - -[ - ![Remmina Desktop Sharing Preferences](http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Configure-Remote-Desk.png) -][6] - -Remmina Desktop Sharing Preferences - -7. After performing all the settings, I will click Connect. Then provide the SSH password for the username and click OK. - -[ - ![Enter SSH User Password](http://www.tecmint.com/wp-content/uploads/2017/03/shared-pass.png) -][7] - -Enter SSH User Password - -I have got this black screen after clicking OK because, on the remote machine, the connection has not been confirmed yet. - -[ - ![Black Screen Before Confirmation](http://www.tecmint.com/wp-content/uploads/2017/03/black-screen-before-confirmat.png) -][8] - -Black Screen Before Confirmation - -8. Now on the remote machine, I have to accept the remote access request by clicking on “Allow” as shown in the next screenshot. - -[ - ![Allow Remote Desktop Sharing](http://www.tecmint.com/wp-content/uploads/2017/03/accept-remote-access-request.png) -][9] - -Allow Remote Desktop Sharing - -9. After accepting the request, I have successfully connected, remotely to my Ubuntu desktop machine. - -[ - ![Remote Ubuntu Desktop](http://www.tecmint.com/wp-content/uploads/2017/03/successfully-connected-to-rem.png) -][10] - -Remote Ubuntu Desktop - -That’s it! In this article, we described how to enable desktop sharing in Ubuntu and Linux Mint. Use the comment section below to write back to us. - --------------------------------------------------------------------------------- - - -作者简介: - -Aaron Kili is a Linux and F.O.S.S enthusiast, an upcoming Linux SysAdmin, web developer, and currently a content creator for TecMint who loves working with computers and strongly believes in sharing knowledge. - --------------------------------------------------------------------------------- - -via: http://www.tecmint.com/enable-desktop-sharing-in-ubuntu-linux-mint/ - -作者:[Aaron Kili][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://www.tecmint.com/author/aaronkili/ - -[1]:http://www.tecmint.com/wp-content/uploads/2017/03/search-for-desktop-sharing.png -[2]:http://www.tecmint.com/wp-content/uploads/2017/03/desktop-sharing-settings-inte.png -[3]:http://www.tecmint.com/wp-content/uploads/2017/03/Configure-Desktop-Sharing-Set.png -[4]:http://www.tecmint.com/remmina-remote-desktop-sharing-and-ssh-client -[5]:http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Desktop-Sharing-Tool.png -[6]:http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Configure-Remote-Desk.png -[7]:http://www.tecmint.com/wp-content/uploads/2017/03/shared-pass.png -[8]:http://www.tecmint.com/wp-content/uploads/2017/03/black-screen-before-confirmat.png -[9]:http://www.tecmint.com/wp-content/uploads/2017/03/accept-remote-access-request.png -[10]:http://www.tecmint.com/wp-content/uploads/2017/03/successfully-connected-to-rem.png -[11]:http://www.tecmint.com/author/aaronkili/ -[12]:http://www.tecmint.com/10-useful-free-linux-ebooks-for-newbies-and-administrators/ -[13]:http://www.tecmint.com/free-linux-shell-scripting-books/ diff --git a/translated/tech/20170403 pyDash – A Web Based Linux Performance Monitoring Tool.md b/translated/tech/20170403 pyDash – A Web Based Linux Performance Monitoring Tool.md new file mode 100644 index 0000000000..9e32f65b97 --- /dev/null +++ b/translated/tech/20170403 pyDash – A Web Based Linux Performance Monitoring Tool.md @@ -0,0 +1,189 @@ +pyDash — 一个基于 web 的 Linux 性能监测工具 +============================================================ + +pyDash 是一个轻量且[基于 web 的 Linux 性能监测工具][1],它是用 Python 和 [Django][2] 加上 Chart.js 来写的。经测试,在下面这些主流 Linux 发行版上可运行:CentOS、Fedora、Ubuntu、Debian、Raspbian 以及 Pidora 。 + +你可以使用这个工具来监视你的 Linux 个人电脑/服务器资源,比如 CPU、内存 +、网络统计,包括在线用户以及更多的进程。仪表盘是完全使用主要的 Python 版本提供的 Python 库开发的,因此它的依赖关系很少,你不需要安装许多包或库来运行它。 + +在这篇文章中,我将展示如果安装 pyDash 来监测 Linux 服务器性能。 + +#### 如何在 Linux 系统下安装 pyDash + +1、首先,像下面这样安装需要的软件包 git 和 Python pip: + +``` +-------------- 在 Debian/Ubuntu 上 -------------- +$ sudo apt-get install git python-pip +-------------- 在 CentOS/RHEL 上 -------------- +# yum install epel-release +# yum install git python-pip +-------------- 在 Fedora 22+ 上 -------------- +# dnf install git python-pip +``` + +2、如果安装好了 git 和 Python pip,那么接下来,像下面这样安装 virtualenv,它有助于处理针对 Python 项目的依赖关系: + +``` +# pip install virtualenv +或 +$ sudo pip install virtualenv +``` + +3、现在,像下面这样使用 git 命令,把 pyDash 仓库克隆到 home 目录中: + +``` +# git clone https://github.com/k3oni/pydash.git +# cd pydash +``` + +4、下一步,使用下面的 virtualenv 命令为项目创建一个叫做 pydashtest 虚拟环境: + +``` +$ virtualenv pydashtest #give a name for your virtual environment like pydashtest +``` +[ + ![Create Virtual Environment](http://www.tecmint.com/wp-content/uploads/2017/03/create-virtual-environment.png) +][3] + +*创建虚拟环境* + +重点:请注意,上面的屏幕截图中,虚拟环境的 bin 目录被高亮显示,你的可能和这不一样,取决于你把 pyDash 目录克隆到什么位置。 + +5、创建好虚拟环境(pydashtest)以后,你需要在使用前像下面这样激活它: + +``` +$ source /home/aaronkilik/pydash/pydashtest/bin/activate +``` +[ + ![Active Virtual Environment](http://www.tecmint.com/wp-content/uploads/2017/03/after-activating-virtualenv.png) +][4] + +*激活虚拟环境* + +从上面的屏幕截图中,你可以注意到,提示字符串 1(PS1)已经发生改变,这表明虚拟环境已经被激活,而且可以开始使用。 + +6、现在,安装 pydash 项目 requirements;如何你是一个细心的人,那么可以使用 [cat 命令][5]查看 requirements.txt 的内容,然后像下面展示这样进行安装: + +``` +$ cat requirements.txt +$ pip install -r requirements.txt +``` + +7、现在,进入 `pydash` 目录,里面包含一个名为 `settings.py` 的文件,也可直接运行下面的命令打开这个文件,然后把 `SECRET_KEY` 改为一个特定值: + +``` +$ vi pydash/settings.py +``` +[ + ![Set Secret Key](http://www.tecmint.com/wp-content/uploads/2017/03/change-secret-key.png) +][6] + +*设置密匙* + +保存文件然后退出。 + +8、之后,运行下面的命令来创建一个项目数据库和安装 Django 的身份验证系统,并创建一个项目的超级用户: + +``` +$ python manage.py syncdb +``` + +根据你的情况回答下面的问题: + +``` +Would you like to create one now? (yes/no): yes +Username (leave blank to use 'root'): admin +Email address: aaronkilik@gmail.com +Password: ########### +Password (again): ############ +``` +[ + ![Create Project Database](http://www.tecmint.com/wp-content/uploads/2017/03/python-manage.py-syncdb.png) +][7] + +*创建项目数据库* + +9、这个时候,一切都设置好了,然后,运行下面的命令来启用 Django 开发服务器: + +``` +$ python manage.py runserver +``` + +10、接下来,打开你的 web 浏览器,输入网址:http://127.0.0.1:8000/ 进入 web 控制台登录界面,输入你在第 8 步中创建数据库和安装 Django 身份验证系统时创建的超级用户名和密码,然后点击登录。 + +[ + ![pyDash Login Interface](http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-web-login-interface.png) +][8] + +*pyDash 登录界面* + +11、登录到 pydash 主页面以后,你将会得到一段监测系统的基本信息,包括 CPU、内存和硬盘使用量以及系统平均负载。 + +向下滚动便可查看更多部分的信息。 + +[ + ![pyDash Server Performance Overview](http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Server-Performance-Overview.png) +][9] + +*pydash 服务器性能概述* + +12、下一个屏幕截图显示的是一段 pydash 的跟踪界面,包括 IP 地址、互联网流量、硬盘读/写、在线用户以及 netstats 。 + +[ + ![pyDash Network Overview](http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Network-Overview.png) +][10] + +*pyDash 网络概述* + +13、下一个 pydash 主页面的截图显示了一部分系统中被监视的活跃进程。 + + +[ + ![pyDash Active Linux Processes](http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Active-Linux-Processes.png) +][11] + +*pyDash 监视活跃 Linux 进程* + +如果想了解更多信息,请在 GitHub 上查看 pydash:[https://github.com/k3oni/pydash][12] + +这就是全部内容了。在这篇文章中,我们展示了在 Linux 中如何安装 pyDash 并测试它的主要特性。如果你有什么想法,可以通过下面的反馈部分联系我们;如果你知道任何有用或类似的工具,也可以在评论中告知我们。 + +-------------------------------------------------------------------------------- + + +作者简介: + +我叫 Ravi Saive,是 TecMint 的创建者,是一个喜欢在网上分享技巧和知识的计算机极客和 Linux Guru 。我的大多数服务器都运行在叫做 Linux 的开源平台上。请关注我:[Twitter][10]、[Facebook][01] 以及 [Google+][02] 。 + +-------------------------------------------------------------------------------- + + +via: http://www.tecmint.com/pydash-a-web-based-linux-performance-monitoring-tool/ + +作者:[Ravi Saive ][a] +译者:[ucasFL](https://github.com/ucasFL) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.tecmint.com/author/admin/ +[00]:https://twitter.com/ravisaive +[01]:https://www.facebook.com/ravi.saive +[02]:https://plus.google.com/u/0/+RaviSaive + +[1]:http://www.tecmint.com/command-line-tools-to-monitor-linux-performance/ +[2]:http://www.tecmint.com/install-and-configure-django-web-framework-in-centos-debian-ubuntu/ +[3]:http://www.tecmint.com/wp-content/uploads/2017/03/create-virtual-environment.png +[4]:http://www.tecmint.com/wp-content/uploads/2017/03/after-activating-virtualenv.png +[5]:http://www.tecmint.com/13-basic-cat-command-examples-in-linux/ +[6]:http://www.tecmint.com/wp-content/uploads/2017/03/change-secret-key.png +[7]:http://www.tecmint.com/wp-content/uploads/2017/03/python-manage.py-syncdb.png +[8]:http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-web-login-interface.png +[9]:http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Server-Performance-Overview.png +[10]:http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Network-Overview.png +[11]:http://www.tecmint.com/wp-content/uploads/2017/03/pyDash-Active-Linux-Processes.png +[12]:https://github.com/k3oni/pydash +[13]:http://www.tecmint.com/author/admin/ +[14]:http://www.tecmint.com/10-useful-free-linux-ebooks-for-newbies-and-administrators/ +[15]:http://www.tecmint.com/free-linux-shell-scripting-books/ diff --git a/translated/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md b/translated/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md new file mode 100644 index 0000000000..d839374229 --- /dev/null +++ b/translated/tech/20170404 How To Enable Desktop Sharing In Ubuntu and Linux Mint.md @@ -0,0 +1,128 @@ +如何在 Ubuntu 和 Linux Mint 上启用桌面共享 +============================================================ + + +桌面共享是指通过图形终端仿真器在计算机桌面上实现远程访问和远程协作的技术。桌面共享允许两个或多个连接到网络的计算机用户在不同位置对同一个文件进行操作。 + +在这篇文章中,我将向你展示如何在 Ubuntu 和 Linux Mint 中启用桌面共享,并展示一些重要的安全特性。 + +### 在 Ubuntu 和 Linux Mint 上启用桌面共享 + +1、在 Ubuntu Dash 或 Linux Mint 菜单中,像下面的截图这样搜索 `desktop sharing`,搜索到以后,打开它。 + +[ + ![Search for Desktop Sharing in Ubuntu](http://www.tecmint.com/wp-content/uploads/2017/03/search-for-desktop-sharing.png) +][1] + +*在 Ubuntu 中搜索 Desktop sharing* + +2、打开 Desktop sharing 以后,有三个关于桌面共享设置的选项:共享、安全以及通知设置。 + +在共享选项下面,选中选项“允许其他用户查看桌面”来启用桌面共享。另外,你还可以选中选项“允许其他用户控制你的桌面”,从而允许其他用户远程控制你的桌面。 + +[ + ![Desktop Sharing Preferences](http://www.tecmint.com/wp-content/uploads/2017/03/desktop-sharing-settings-inte.png) +][2] + +*桌面共享偏好* + +3、接下来,在“安全”部分,你可以通过勾选选项“你必须确认任何对该计算机的访问”来手动确认每个远程连接。 + +另外,另一个有用的安全特性是通过选项“需要用户输入密码”创建一个确定的共享密码。这样当用户每次想要访问你的桌面时需要知道并输入密码。 + +4、对于通知,你可以勾选“仅当有人连接上时”来监视远程连接,这样每次当有人远程连接到你的桌面时,可以在通知区域查看。 + +[ + ![Configure Desktop Sharing Set](http://www.tecmint.com/wp-content/uploads/2017/03/Configure-Desktop-Sharing-Set.png) +][3] + +*配置桌面共享设置* + +当所有的桌面共享选项都设置好以后,点击“关闭”。现在,你已经在你的 Ubuntu 或 Linux Mint 上成功启用了桌面共享。 + +### 测试 Ubuntu 的远程桌面共享 + +你可以通过使用一个远程连接应用来进行测试,从而确保桌面共享可用。在这个例子中,我将展示上面设置的一些选项是如何工作的。 + +5、我将使用 VNC(虚拟网络计算)协议通过 [remmina 远程连接应用][4]连接到我的 Ubuntu PC。 + +[ + ![Remmina Desktop Sharing Tool](http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Desktop-Sharing-Tool.png) +][5] + +*Remmina 桌面共享工具* + +6、在点击 Ubuntu PC 以后,将会出现下面这个配置连接设置的界面, + +[ + ![Remmina Desktop Sharing Preferences](http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Configure-Remote-Desk.png) +][6] + +*Remmina 桌面共享偏好* + +7、当执行好所有设置以后,点击连接。然后,给用户名提供 SSH 密码并点击 OK 。 + +[ + ![Enter SSH User Password](http://www.tecmint.com/wp-content/uploads/2017/03/shared-pass.png) +][7] + +*输入 SSH 用户密码* + +点击确定以后,出现下面这个黑屏,这是因为在远程机器上,连接还没有确认。 + +[ + ![Black Screen Before Confirmation](http://www.tecmint.com/wp-content/uploads/2017/03/black-screen-before-confirmat.png) +][8] + +*连接确认前的黑屏* + +8、现在,在远程机器上,我需要像下一个屏幕截图显示的那样点击 `Allow` 来接受远程访问请求。 + +[ + ![Allow Remote Desktop Sharing](http://www.tecmint.com/wp-content/uploads/2017/03/accept-remote-access-request.png) +][9] + +*允许远程桌面共享* + +9、在接受请求以后,我就成功地连接到了远程 Ubuntu 机器的桌面。 + +[ + ![Remote Ubuntu Desktop](http://www.tecmint.com/wp-content/uploads/2017/03/successfully-connected-to-rem.png) +][10] + +*远程 Ubuntu 桌面* + +这就是全部内容了,在这篇文章中,我们讲解了如何在 Ubuntu 和 Linux Mint 中启用桌面共享。你使用评论部分给我们写反馈。 + +-------------------------------------------------------------------------------- + + +作者简介: + +Aaron Kili 是 Linux 和 F.O.S.S 爱好者,将来的 Linux 系统管理员和网络开发人员,目前是 TecMint 的内容创作者,他喜欢用电脑工作,并坚信分享知识。 + +-------------------------------------------------------------------------------- + +via: http://www.tecmint.com/enable-desktop-sharing-in-ubuntu-linux-mint/ + +作者:[Aaron Kili][a] +译者:[ucasFL](https://github.com/ucasFL) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.tecmint.com/author/aaronkili/ + +[1]:http://www.tecmint.com/wp-content/uploads/2017/03/search-for-desktop-sharing.png +[2]:http://www.tecmint.com/wp-content/uploads/2017/03/desktop-sharing-settings-inte.png +[3]:http://www.tecmint.com/wp-content/uploads/2017/03/Configure-Desktop-Sharing-Set.png +[4]:http://www.tecmint.com/remmina-remote-desktop-sharing-and-ssh-client +[5]:http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Desktop-Sharing-Tool.png +[6]:http://www.tecmint.com/wp-content/uploads/2017/03/Remmina-Configure-Remote-Desk.png +[7]:http://www.tecmint.com/wp-content/uploads/2017/03/shared-pass.png +[8]:http://www.tecmint.com/wp-content/uploads/2017/03/black-screen-before-confirmat.png +[9]:http://www.tecmint.com/wp-content/uploads/2017/03/accept-remote-access-request.png +[10]:http://www.tecmint.com/wp-content/uploads/2017/03/successfully-connected-to-rem.png +[11]:http://www.tecmint.com/author/aaronkili/ +[12]:http://www.tecmint.com/10-useful-free-linux-ebooks-for-newbies-and-administrators/ +[13]:http://www.tecmint.com/free-linux-shell-scripting-books/ From 553afa1469c7123af02c0615fce30bb73294fec1 Mon Sep 17 00:00:00 2001 From: wxy Date: Sat, 15 Apr 2017 16:21:07 +0800 Subject: [PATCH 17/37] PUB:20161216 The truth about traditional JavaScript benchmarks.md @Vic020 --- ... for Gos Regions and Endpoints Metadata.md | 42 ++++++++----------- ...about traditional JavaScript benchmarks.md | 26 +++++++----- 2 files changed, 34 insertions(+), 34 deletions(-) rename {translated/tech => published}/20170116 Using the AWS SDK for Gos Regions and Endpoints Metadata.md (52%) diff --git a/translated/tech/20170116 Using the AWS SDK for Gos Regions and Endpoints Metadata.md b/published/20170116 Using the AWS SDK for Gos Regions and Endpoints Metadata.md similarity index 52% rename from translated/tech/20170116 Using the AWS SDK for Gos Regions and Endpoints Metadata.md rename to published/20170116 Using the AWS SDK for Gos Regions and Endpoints Metadata.md index aa7564e8e3..7805a6d6a1 100644 --- a/translated/tech/20170116 Using the AWS SDK for Gos Regions and Endpoints Metadata.md +++ b/published/20170116 Using the AWS SDK for Gos Regions and Endpoints Metadata.md @@ -1,20 +1,17 @@ -使用AWS的GO SDK获取区域与终端节点信息 +使用 AWS 的 GO SDK 获取区域与终端节点信息 ============================================================ -
+LCTT 译注: 终端节点(Endpoint),详情请见: [http://docs.amazonaws.cn/general/latest/gr/rande.html](http://docs.amazonaws.cn/general/latest/gr/rande.html) -译注: Endpoint(终端节点)[详情请见: http://docs.amazonaws.cn/general/latest/gr/rande.html](http://docs.amazonaws.cn/general/latest/gr/rande.html) +最新发布的 GO 的 SDK [v1.6.0][1] 版本,加入了获取区域与终端节点信息的功能。它可以很方便地列出区域、服务和终端节点的相关信息。可以通过 [github.com/aws/aws-sdk-go/aws/endpoints][3] 包使用这些功能。 -最新发布的GO的SDK[v1.6.0][1]版本, 加入了获取区域与终端节点信息的功能. 它可以很方便地列出区域, 服务 和终端节点的相关信息.可以通过[github.com/aws/aws-sdk-go/aws/endpoints][3]包使用这些功能. - -endpoints包提供了一个易用的接口,可以获取到一个服务的终端节点的url列表和区域列表信息.并且我们将相关信息根据AWS服务区域进行了分组,如 AWS 标准, AWS 中国, and AWS GovCloud (美国). +endpoints 包提供了一个易用的接口,可以获取到一个服务的终端节点的 url 列表和区域列表信息。并且我们将相关信息根据 AWS 服务区域进行了分组,如 AWS 标准、AWS 中国和 AWS GovCloud(美国)。 ### 解析终端节点 -设置SDK的默认配置时, SDK会自动地使用endpoints.DefaultResolver函数. 你也可以自己调用包中的EndpointFor方法来解析终端节点. +设置 SDK 的默认配置时, SDK 会自动地使用 `endpoints.DefaultResolver` 函数。你也可以自己调用包中的`EndpointFor` 方法来解析终端节点。 -Go -``` +```Go // 解析在us-west-2区域的S3服务的终端节点 resolver := endpoints.DefaultResolver() endpoint, err := resolver.EndpointFor(endpoints.S3ServiceID, endpoints.UsWest2RegionID) @@ -26,12 +23,12 @@ if err != nil { fmt.Println("Resolved URL:", endpoint.URL) ``` -如果你需要自定义终端节点的解析逻辑,你可以实现endpoints.Resolver接口, 并传值给aws.Config.EndpointResolver. 当你打算编写自定义的终端节点逻辑,让sdk可以用来解析服务的终端节点时候,这个功能就会很有用. +如果你需要自定义终端节点的解析逻辑,你可以实现 `endpoints.Resolver` 接口,并传值给`aws.Config.EndpointResolver`。当你打算编写自定义的终端节点逻辑,让 SDK 可以用来解析服务的终端节点时候,这个功能就会很有用。 -以下示例, 创建了一个配置好的Session, 然后[Amazon S3][4]服务的客服端就可以使用这个自定义的终端节点. +以下示例,创建了一个配置好的 Session,然后 [Amazon S3][4] 服务的客户端就可以使用这个自定义的终端节点。 -Go -``` + +```Go s3CustResolverFn := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) { if service == "s3" { return endpoints.ResolvedEndpoint{ @@ -52,10 +49,9 @@ sess := session.Must(session.NewSessionWithOptions(session.Options{ ### 分区 -endpoints.DefaultResolver函数的返回值可以被endpoints.EnumPartitions接口使用.这样就可以获取SDK使用的分区片段,也可以列出每个分区的分区信息。 +`endpoints.DefaultResolver` 函数的返回值可以被 `endpoints.EnumPartitions`接口使用。这样就可以获取 SDK 使用的分区片段,也可以列出每个分区的分区信息。 -Go -``` +```Go // 迭代所有分区表打印每个分区的ID resolver := endpoints.DefaultResolver() partitions := resolver.(endpoints.EnumPartitions).Partitions() @@ -65,10 +61,9 @@ for _, p := range partitions { } ``` -除了分区表之外, endpoints包也提供了每个分区组的getter函数. 这些工具函数可以方便列出指定分区,而不用执行默认解析器列出所有的分区. +除了分区表之外,endpoints 包也提供了每个分区组的 getter 函数。这些工具函数可以方便列出指定分区,而不用执行默认解析器列出所有的分区。 -Go -``` +```Go partition := endpoints.AwsPartition() region := partition.Regions()[endpoints.UsWest2RegionID] @@ -78,19 +73,18 @@ for id, _ := range region.Services() { } ``` -当你获取区域和服务值后, 可以调用ResolveEndpoint. 这样解析端点时,就可以提供分区的过滤视图. +当你获取区域和服务值后,可以调用 `ResolveEndpoint`。这样解析端点时,就可以提供分区的过滤视图。 -获取更多AWS SDK for GO信息, 请关注[开源库][5]. 若你有更好的看法,请留言评论. +获取更多 AWS SDK for GO 信息, 请关注[其开源仓库][5]。若你有更好的看法,请留言评论。 -
-------------------------------------------------------------------------------- via: https://aws.amazon.com/cn/blogs/developer/using-the-aws-sdk-for-gos-regions-and-endpoints-metadata -作者:[ Jason Del Ponte][a] +作者:[Jason Del Ponte][a] 译者:[Vic020](http://vicyu.com) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20161216 The truth about traditional JavaScript benchmarks.md b/translated/tech/20161216 The truth about traditional JavaScript benchmarks.md index 1a4b281fda..5b0ea6b2de 100644 --- a/translated/tech/20161216 The truth about traditional JavaScript benchmarks.md +++ b/translated/tech/20161216 The truth about traditional JavaScript benchmarks.md @@ -1,29 +1,35 @@ 探索传统 JavaScript 基准测试 ============================================================ -可以很公平地说,[JavaScript][22] 是当下软件工程最重要的技术。对于那些深入接触过编程语言、编译器和虚拟机的人来说,这仍然有点令人惊讶,因为在语言设计者看来,JavaScript 不是十分优雅;在编译器工程师看来,它没有多少可优化的地方;而且还没有一个伟大的标准库。这取决于你和谁吐槽,JavaScript 的缺点你花上数周都枚举不完,不过你总会找到一些你从所未知的神奇的东西。尽管这看起来明显困难重重,不过 JavaScript 还是成为当今 web 的核心,并且还成为服务器端/云端的主导技术(通过 [Node.js][23]),甚至还开辟了进军物联网空间的道路。 +可以很公平地说,[JavaScript][22] 是当下软件工程最重要的技术。对于那些深入接触过编程语言、编译器和虚拟机的人来说,这仍然有点令人惊讶,因为在语言设计者们看来,JavaScript 不是十分优雅;在编译器工程师们看来,它没有多少可优化的地方;而且还没有一个伟大的标准库。这取决于你和谁吐槽,JavaScript 的缺点你花上数周都枚举不完,不过你总会找到一些你从所未知的神奇的东西。尽管这看起来明显困难重重,不过 JavaScript 还是成为了当今 web 的核心,并且还(通过 [Node.js][23])成为服务器端/云端的主导技术,甚至还开辟了进军物联网空间的道路。 -问题来了,为什么 JavaScript 如此受欢迎?或者说如此成功?我知道没有一个很好的答案。如今我们有许多使用 JavaScript 的好理由,或许最重要的是围绕其构建的庞大的生态系统,以及今天大量可用的资源。但所有这一切实际上是发展到一定程度的后果。为什么 JavaScript 变得流行起来了?嗯,你或许会说,这是 web 多年来的通用语了。但是在很长一段时间里,人们极其讨厌 JavaScript。回顾过去,似乎第一波 JavaScript 浪潮爆发在上个年代的后半段。不出所料,那个时候 JavaScript 引擎加速了各种不同的任务的执行,这可能让很多人对 JavaScript 刮目相看。 +问题来了,为什么 JavaScript 如此受欢迎?或者说如此成功?我知道没有一个很好的答案。如今我们有许多使用 JavaScript 的好理由,或许最重要的是围绕其构建的庞大的生态系统,以及今天大量可用的资源。但所有这一切实际上是发展到一定程度的后果。为什么 JavaScript 变得流行起来了?嗯,你或许会说,这是 web 多年来的通用语了。但是在很长一段时间里,人们极其讨厌 JavaScript。回顾过去,似乎第一波 JavaScript 浪潮爆发在上个年代的后半段。那个时候 JavaScript 引擎加速了各种不同的任务的执行,很自然的,这可能让很多人对 JavaScript 刮目相看。 -回到过去那些日子,这些加速测试使用了现在所谓的传统 JavaScript 基准——从苹果的 [SunSpider 基准][24](JavaScript 微基准之母)到 Mozilla 的 [Kraken 基准][25] 和谷歌的 V8 基准。后来,V8 基准被 [Octane 基准][26] 取代,而苹果发布了新的 [JetStream 基准][27]。这些传统的 JavaScript 基准测试驱动了无数人的努力,使 JavaScript 的性能达到了本世纪初没人能预料到的水平。据报道加速达到了 1000 倍,一夜之间在网站使用 `