分类 技术 下的文章

代码中的缩进指的是你在代码行的开头处的空格。像其他代码编辑器和 IDE 一样,VSCode 允许你自动缩进你的代码。

你可以设置使用制表符或空格或任何你喜欢的缩进方式。

听起来不错吧?让我们来看看怎么做。

在 VSCode 中启用自动缩进

你有多种方法可以实现这个目标。在本指南中,我将向你展示三种在 VSCode 中自动缩进代码的方法。

方法 1:配置全局用户设置

你可以通过命令模式访问全局用户设置。使用 Ctrl + Shift + P 来打开命令模式,搜索 Open User Settings 并按下回车:

access user setting from command pallet in vscode

它将打开设置。在那里,你需要搜索 Auto Indent,并在 “ 编辑器:自动缩进 Editor: Auto Indent ” 中选择 “ 全部 Full ”:

enable auto indent from global user settings in vscode

接着自动缩进会被启用,并应用于 VSCode 中每个打开的文件。

方法 2:在 VSCode 中使用检查器或格式化工具进行自动缩进

在这种方法中,你需要添加扩展程序,如代码格式化工具或者检查器,以获得理想的结果。

检查器 Linter 会识别代码中的错误,而 格式化工具 Formatter 只对你的代码进行格式化,使其更具可读性。你可以在 VSCode 市场 中搜索特定于你的编程语言的代码格式化器。

这里有一些我最喜欢的广泛流行语言的代码格式化工具和检查器:

  • C/C++:适用于 C 和 C++ 编程语言。
  • PHP:适用于 PHP。
  • markdownlint:适用于 Markdown 文件。
  • Python:适用于 Python 编程语言。
  • ESLint:适用于 JSON 和 javascript。
  • Beautify: 适用于 JavaScript、JSON、CSS、SASS 和 HTML。

当你为你喜欢的编程语言添加了格式化工具,你可以按 Ctrl + Shift + I 来格式化代码。

同样地,你也可以使用命令模式做同样的事情。按 Ctrl + Shift + P,并搜索 Format document,然后按下回车。

indent code in VSCode

方法 3:在保存文件时启用自动缩进功能

VSCode 允许你在保存你的代码时,通过一个小小的调整来格式化它。让我告诉你怎么做。

Ctrl + ,,它将打开用户设置提示。在那里,搜索 Format On Save

enable format on save option

从现在开始,当你保存文件时,你的文件将自动添加缩进。

总结

在本指南中,我解释了如何在 VSCode 中自动添加缩进。我建议使用第二种方法以获得更好的灵活性。

我希望你会发现本指南对你有帮助,如果你有任何疑问或建议,请在评论中告诉我。


via: https://itsfoss.com/auto-indent-vs-code/

作者:Sagar Sharma 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

只要对汇编有一点基本的了解,这些函数就能扩展到任意位长的整型数学运算。

几年前,我为 FreeDOS 写了一个叫做 VMATH 的命令行数学程序。它只能在很小的无符号整型上执行十分简单的数学运算。随着近来 FreeDOS 社区里对基础数学的兴趣,我改进了 VMATH 使其可以为有符号 64 位整型提供基本的数学支持。

仅使用 16 位 8086 兼容的汇编指令来操控大型数字的过程并不简单。我希望能够分享一些在 VMATH 中用到的技术例子。其中一些方法掌握起来相当容易。而另外一些方法则看起来有点奇怪。你甚至可能学到一种进行基本数学运算的全新方式。

接下来要讲的加、减、乘、除会用到的技术将不局限于并不局限于 64 位整型。只要对汇编有一点基本的了解,这些函数就能扩展到任意位长的整型数学运算。

在深入研究这些数学函数前,我想先从计算机的角度介绍一下数字的一些基本知识。

计算机是如何读取数字的

一个英特尔兼容的 CPU 以 字节 Byte 的形式贮存数字,储存顺序为从最低有效字节到最高有效字节。每个字节由 8 个二进 Bit 组成,两个字节组成一个 Word

一个储存在内存里的 64 位整型占用了 8 个字节(即 4 个字)。例如,数字 74565(十六进制表示为 0x12345)的值长得是这个样子的:

用字节表示:db 0x45, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
用字表示:dw 0x2345, 0x0001, 0x0000, 0x0000

当读取或写入数据到内存时,CPU 会以正确的顺序处理这些字节。对于比 8086 更现代的处理器而言,数据分组可以再大些,比如一个 四字组 Quadword 就可以表达整个 64 位整型 0x0000000000012345

8086 CPU 不能理解这么大的数字。当为 FreeDOS 编程时,你想要写的是一个能在任意电脑上跑的程序,甚至是原始的 IBM PC 5150。你想要使用能够扩展到任意大小整型的技术。我们其实并不关心更现代 CPU 的能力。

为了能做整型运算,我们的数据需要表达两种不同类型的数字。

第一种是 无符号 unsigned 整型,其使用了所有的位来表达一个正数。无符号整型的值域为从 02<sup> 位长</sup> - 1。例如,8 位数可以是 0255 之间的任意值,而 16 位数则在 065535 之间,以此类推。

有符号整型也很类似。不同之处在于数字的最高位代表了这个数是一个正数(0)还是一个负数 (1)。有符号整型的值域前半部分为正数,正数值域是从 02<sup> 位长 - 1</sup> - 1。整型值域的后半部分为负数,负数值域则从 0 - 2<sup> 位长 - 1</sup>-1

比如说,一个 8 位数代表着 0127 之间的任意正数,以及 -128-1 之间的任意负数。为了能更好的理解这一点,想象 字节 为一列数组 [0...127,-128...-1]。因为 -128 在数组内紧跟着 1271271 等于 -128。当然这可能看起来有点奇怪甚至反常,但这其实让这个层级的基本数学运算变简单了。

为了能够对大型整型进行简单的加、减、乘、除,你应该摸索一些简单的公式来计算一个数的绝对值或负值。你在做有符号整型运算的时候会用上它们的。

绝对值与负值

计算一个有符号整型的绝对值并没有它看起来的那么糟糕。由于无符号和有符号数字在内存里的储存形式,我们其实有一个简单的方案。你只需要翻转一个负数的所有字位,得出的结果再加 1

如果你从没接触过二进制的话,这可能听上去有点奇怪,但这就是这么工作的。让我们来举一个例子,取一个负数的 8 位表达,比如说 -5。因为 -5 靠近 [0...127,-128...-1] 字节组末端,它的十六进制值为 0xfb,二进制值为 11111011。如果你翻转了所有字位,你会得到 0x04 或二进制值 00000100。结果加 1 你就得到了你的答案:你刚刚把 -5 的值变成了 +5

你可以用汇编写下这个程序用以返回任意 64 位数字的绝对值:

; 语法,NASM for DOS
proc_ABS:
  ; 启动时,SI 寄存器会指向数据段(DS)内的内存位置,那里存放着程序内包含着
  ; 会被转为正数的 64 位数。
  ; 结束时,如果结果数字不能被转正,CF 寄存器会被设置。这种情况只
  ; 有在遇到最大负值时会发生。其余情况,CF 不会被设置。
  
  ; 检查最高字节的最高位
  test [si+7], byte 0x80
  ; 如不为 1,值为正值
  jz .done_ABS
  ; 翻转所有位
  not word [si+6]       ; 字 #4
  not word [si+4]       ; 字 #3
  not word [si+2]       ; 字 #2
  not word [si]         ; 字 #1
  ; 字 #1 加 1
  inc word [si]
  ; 如结果不为 0,结束
  jnz .done_ABS
  ; 字 #2 加 1
  inc word [si+2]
  ; 如结果为 0,进位下一个字
  jnz .done_ABS
  inc word [si+4]
  jnz .done_ABS
  ; 此处无法进位
  inc word [si+6]
  ; 再一次检查最高位
  test [si+7], byte 0x80
  ; 如不为 1,我们成功了,结束
  jz .done_ABS
  ; 溢出错误,它被转成了负数
  stc
  ; 设置 CF 并返回
  ret
.done_ABS:
  ; 成功,清理 CF 并返回
  clc
  ret

你可能已经注意到了,这个函数有一个潜在问题。由于正数和负数的二进制值表达方式,最大负数无法被转成正数。以 8 位数为例,最大负数是 -128。如果你翻转了 -128 的所有位数(二进制 1__0000000),你会得到 127(二进制 0__1111111)这个最大正值。如果你对结果加 1,它会因溢出回到同样的负数(-128)。

要将正数转成负数,你只需要重复计算绝对值的步骤就行。以下的程序十分相似,你唯一需要确认的就是一开始的数字不是已经负了。

; 语法, NASM for DOS
proc_NEG:
  ; 开始时,SI 会指向需要转负的数字在内存里的位置。
  ; 结束时,CF 永远不会被设置。
  
  ; 检查最高字节的最高位
  test [si+7], byte 0x80
  ; 如为 1,数已经是负数
  jnz .done_NEG
  not word [si+6]       ; 翻转字的所有位,字 #4
  not word [si+4]       ; 字 #3
  not word [si+2]       ; 字 #2
  not word [si]         ; 字 #1
  inc word [si]         ; 字 #1 加 1
  ; 如结果不为 0,结束
  jnz .done_NEG
  ; 字 #2 加 1
  inc word [si+2]
  ; 如结果为 0,进位下一个字
  jnz .done_NEG
  inc word [si+4]
  jnz .done_NEG
  ; 此处无法进位或转化
  inc word [si+6]
  ; 正。
.done_NEG:
  clc                   ; 成功,清理 CF 并返回
  ret

看着这些绝对值函数与负值函数间的通用代码,它们应该被合并起来节约一些字节。合并代码也会带来额外的好处。首先,合并代码能帮助防止简单的笔误。这样也可以减少测试的要求。进一步来讲,这样通常会让代码变得简单易懂。在阅读一长串的汇编指令时,忘记读到哪里是常有的事。现在,我们可以不管这些。

计算一个数的绝对值或负值并不难。但是,这些函数对于我们即将开始的有符号整型数学运算至关重要。

我已经介绍了整型数字在位这一层面的基本表示方法,也创造了可以改变这些数字的基本程序,现在我们可以做点有趣的了。

让我们来做些数学运算吧!


via: https://opensource.com/article/22/10/64-bit-math

作者:Jerome Shidel 选题:lkxed 译者:yzuowei 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这篇指南可以让你如何摆脱 Ubuntu 的无趣的登录背景屏幕,并在你每次登录时设置一张漂亮的图片来欢迎你。

我总是认为,在你启动你的系统后,应该有一个漂亮的登录屏幕来欢迎你。这本身就为你即将开始的工作或活动渲染了愉快的氛围。尽管,我不是一名 Windows 的粉丝,但是我很欣赏 Windows 10 的登录背景都会每天随着 Bing 壁纸进行更改,它看起来好极了,对吧?

前段时间,我们讨论了如何 更改 Fedora 的登录屏幕背景更改 elementary OS 的登录屏幕背景 。现在这篇指南将向你解释,如何更改使用 GNOME Shell 的 Ubuntu 的登录屏幕背景。

登录屏幕背景是显示管理器(DM)属性的一部分。这篇指南将使用一位用户在 GitHub 中创建的一个脚本,使得普通用户也能简单易用。否则,你需要在提取 .gresource 文件后,必须手动更改 Gnome 显示管理器 Gnome Display Manager (GDM)的 CSS 文件,接下来再编译它。一般来说,这是很复杂的。

Ubuntu 登录屏幕 – 在更改前

更改 Ubuntu 的登录背景

打开一个终端(按下组合键 CTRL+ALT+T)。

使用下面的命令,下载这个 GitHub 仓库

wget github.com/thiggy01/change-gdm-background/raw/master/change-gdm-background

注意: 如果你没有 wget ,使用 sudo apt install wget 来安装它。

Ubuntu 22.04 Jammy Jellyfish 用户需要更改一些额外的代码来使其工作,因为,在 GitHub 仓库中,开发者没有修复它。因此,在这里你需要自己来更改。

使用 gedit 来打开 change-gdm-background 文件。接下来,转到下面的行(#15) 并添加 |jammy

脚本更改为允许 jammy

接下来,转到下面的两行(#144#184)。将 gdm3.css 更改为 gdm.css 。如下图所示。

修正针对 gdm 的 css 文件

最后,保存文件,并遵循如下的操作指南。这种解决方法只适用于 Ubuntu 22.04 的登录屏幕的更改。

更改脚本的权限来使其可执行:

chmod +x change-gdm-background

接下来,更改 Ubuntu 的登录背景壁纸,使用下面的命令。按照你的图片相应地更改路径:

sudo ./change-gdm-background ~/Pictures/tree.jpg

这一步骤可能需要 libglib2.0-dev 软件包,它将会自动地安装。提取和编译 .gresource 会用到它。

在安装后,它应该会提示你重新启动 GDM 。慎重起见,按下 N 按键。

注销后,你可以看到更改后的 Ubuntu 的背景。

如果你没有看到更改,尝试重新启动你的系统,然后尝试登录。

在更改后的,Ubuntu 的登录屏幕背景

恢复先前的登录屏幕

该脚本也提供了一种恢复先前的登录屏幕的特色功能。它在更改你的 .gresource 文件前,会将其进行备份。因此,恢复先前的登录屏幕,只需要在终端中简单地运行下面的命令。

sudo ./change-gdm-background --restore

这应该会将其登录屏幕更改回其先前的形式。

请在下面的评论框中,让我知道这篇指南的内容是否对你有效果,这应该适用于所有的最新版本的 Ubuntu Linux 。


via: https://www.debugpoint.com/change-login-background-ubuntu/

作者:Arindam 选题:lkxed 译者:robsean 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

了解 for 循环结构和你在控制它时拥有的选项,这样你可以对如何在 Lua 中处理数据做出聪明的决定。

在编程中,迭代是一个重要的概念,因为代码通常必须多次扫描一组数据,以便它可以单独处理每个项目。控制结构使你能够根据通常在程序运行时动态建立的条件来指导程序的流程。不同的语言提供不同的控制,在 Lua 中,有 while 循环、for 循环和 repeat until 循环。本文介绍 for 循环。我将在另一篇文章中介绍 whilerepeat until 循环。

for 循环

for 循环接受已知数量的项目并确保处理每个项目。“项目”可以是数字,它也可以是一个包含多个条目或任何 Lua 数据类型的表。语法和逻辑有点灵活,但语法允许这些参数,每个参数本质上描述了一个计数器:

  • 计数器的起始值
  • 停止值
  • 你希望计数器前进的增量

例如,假设你有三个项目并希望 Lua 处理每个项目。你的计数器可以从 3 开始一直持续到 1,增量为 -1。这呈现为 3、2、1 的计数。

mytable = { "zombie", "Halloween", "apocalypse" }
for count = 3, 1, -1 do
  print(count .. ": " .. mytable[count])
end

运行代码以确保所有三个项目都得到处理:

$ lua ./for.lua
3: apocalypse
2: Halloween
1: zombie

这段代码有效地“反向”处理了表,因为它是倒数。你可以正数:

for count = 1, 3, 1 do
  print(mytable[count])
end

此示例从最低索引到最高索引处理表:

$ lua ./for.lua
1: zombie
2: Halloween
3: apocalypse

增量

你也可以更改增量。例如,也许你想要一个没有万圣节盛况的僵尸启示录:

mytable = { "zombie", "Halloween", "apocalypse" }
for count = 1, 3, 2 do
  print(mytable[count])
end

运行代码:

$ lua ./for.lua
zombie
apocalypse

该示例打印了 1 和 3,因为第一个计数是 1,然后递增 2(总共 3)。

计数器

有时你不知道需要 Lua 遍历数据的次数。在这种情况下,你可以将计数器设置为由其他进程填充的变量。

另外,count 这个词不是关键字。为了清楚起见,这正是我在示例代码中使用的内容。程序员通常使用更短的名称,例如 ic

var = os.time()
if var%2 == 0 then
  mytable = { var }
else
  mytable = { "foo", "bar", "baz" }
end
for c = 1, #mytable, 1 do
  print(mytable[c])
end

此代码创建一个变量,其中包含启动时的时间戳。如果时间戳是偶数(除以 2 时模数为 0),则只将时间戳放入表中。如果时间戳是奇数,它将三个字符串放入一个表中。

现在你无法确定你的 for 循环需要运行多少次。可能是一次或是三次,但没有办法确定。解决方案是将起始计数设置为 1,将最终计数设置为表的长度(#mytable 是确定表长度的内置快捷方式)。

可能需要多次运行脚本才能看到这两个结果,但最终,你会得到如下结果:

$ lua ./dynamic.lua1665447960
$ lua ./dynamic.lua
foo
bar
baz

带 pairs 和 ipairs 的 for 循环

如果你已经阅读了我关于 表迭代 的文章,那么你已经熟悉了 Lua 中最常见的 for 循环之一。这个使用 pairsipairs 函数来迭代一个表:

mytable = { "zombie", "Halloween", "apocalypse" }
for i,v in ipairs(mytable) do
  print(i .. ": " v)
end

pairsipairs 函数“解包”表并将值转储到你提供的变量中。在此示例中,我将 i 用于 索引,将 v 用于 ,但变量名称无关紧要。

$ lua ./for.lua1: zombie2: Halloween3: apocalypse

for 循环

for 循环结构在编程中很常见,由于经常使用表和 pairs 函数,因此在 Lua 中非常常见。了解 for 循环结构和控制它时的选项意味着你可以就如何在 Lua 中处理数据做出明智的决定。


via: https://opensource.com/article/22/11/lua-for-loops

作者:Seth Kenlon 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

学习如何使用 Git 来压扁、变基和精选。

当我与别人谈到 Git 时,几乎每个人都对 git rebase 命令 有强烈的印象,这个命令让许多人遇到了问题,而不得不更改目录、删除仓库、然后再重新克隆一个仓库。我认为这是因为他们误解了分支是如何工作,遇到了一个非常糟糕的默认界面,还有一些合并冲突把事情搞得一团糟。

怎么找不到 git squash 命令?

如果你曾在本地的仓库提交过很多次,并希望能把这些提交都合并为一个提交,接下来,我们就来介绍能用什么 Git 命令达到这个目的。Git 称这个概念为 “ 压扁提交 squash commits ”。我在编写文档时发现了这个概念:我花了十几个提交才修改好我的 Markdown 文档,但是仓库的维护者不想看到我的所有尝试,以免扰乱了该项目的历史,所以我被告知“需要压扁你的提交”。

压扁提交听起来是一个很有用的方法。但是只有一个问题:我不知道该怎么做。作为 Git 的新手,我做了任何人会做的事情:我去查阅 git-squash 的手册,但我立即遇到了阻碍:

$ man git-squash
> No manual entry for git-squash

我发现没有一个名为 squash 的 Git 命令,而是被要求 运行一个完全独立的命令:git rebase 命令,该命令能将我的所有提交最终合并为一个提交。

我知道我碰到一个常见的情形:已经使用工具一段时间的人使用了行话或引用了一个概念,这个概念对他们来说是非常清楚的,但对新手来说就不能明白了。从概念上讲,这个情况看起来是这样的:

Image of 6 bowls of different colored spices, and an arrow pointing to the second image of all the spices blended into one bowl.

我这样说是为了鼓励你,你绝对不是第一个或最后一个 被 Git 或谈论 Git 的人 弄糊涂的人。你可以要求对方说明白他的意见,并帮助你应该使用的正确命令。仓库的维护者实际上的意思是,“使用 git rebase 命令**,将很多提交压扁成一个提交”。

现在就来学习 git rebase 命令吧

git rebase 命令会将一个提交链从其第一个父级中删除,并将其放置在另一个提交链的末尾,将两个提交链组合成一个长链,而不是两个并行链。我意识到这是一个很复杂的定义。

回想一下 Git 的提交是如何链接在一起的,你可以看到,除了初始的 main(或 master)分支外,任何分支都有一个 父提交 parent commit 作为该链的 “ 基础 base ”。“ 变基 rebase ” 能使另一个链中的最后一个提交成为指定分支的新 “ 基础提交 base commit ”。

在 Git 中整合来自不同分支的修改主要有两种方法: 合并 merge 以及 变基 rebase ,你可能更熟悉 git merge 命令。接下来,就来看看 [git-scm.com] 是如何解释 git mergegit rebase 的差异:

Image of Git merge versus git rebase shown as numbered bubbles.

在合并示例中,它会把两个分支的最新快照(C3C4)以及二者最近的共同祖先(C2)进行三方合并,合并的结果是生成一个新的快照(C5)。experiment 的分支指针仍然存在,仍然指向 C4

在变基示例中,它提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次,使 C3 成为 C4 的新父级,并产生了一个名为 C4' 的新提交。

(LCTT 译注:具体的命令如下:

$ git checkout experiment
$ git rebase main
First, rewinding head to replay your work on top of it...
Applying: added staged command

它的原理是首先找到这两个分支 —— 即当前分支 experiment、变基操作的目标基底分支 main —— 的最近共同祖先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底 C3,最后以此将之前另存为临时文件的修改依序应用。)

值得注意的是,分支指针 main 没有移动。要让 Git 将指针移动到链的末尾(由experiment 指向),你还需要执行合并。

(LCTT 译注:具体的命令如下:

$ git checkout main
$ git merge experiment

master 分支的快进合并

此时,C4' 指向的快照就和上面使用 merge 命令的例子中 C5 指向的快照一模一样了。)

git rebase 并不能替代 git mergegit rebase 是一种用于制作更清晰的历史记录,以与 git merge 结合使用的工具。

(LCTT 译注:使用 git rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。)

交互式变基能给你一个更友好的界面!

从命令行执行 git rebase 命令,最可怕的地方在于它糟糕的默认界面。运行命令 git rebase <target-refr> 要么有效,要么会变得一团糟,因为它没有太多的反馈或方法来确保它做你想做的事情。幸运的是,git rebase 命令和许多其他 Git 命令一样,具有 交互模式 interactive mode ,你可以使用参数 -i 或者 -interactive 来使用交互模式。

Image of the Git lens interactive Rebase tool in VS Code.

在使用交互式模式时,git rebase 会从一个糟糕的黑框界面转换为一个选项菜单,允许你选择对正在变基的提交链所做的事。对于每个提交,你可以选择

  • 选用 pick :按原样包含
  • 重写 reword :重写提交消息
  • 编写 edit :在变基完成之前对提交中的文件进行进一步更改
  • 压扁 squash :将多个提交压缩成一个提交,保留所有提交消息
  • 修理 fixup :将多个提交压缩成一个提交,但只保留最后一个提交消息
  • 丢弃 drop :丢弃此提交

就我个人而言,我更喜欢 VS Code 的开源 GitLens 扩展 使用下拉选择列表布局选项的方式,但 Git 允许你使用任何编辑器选择这些选项。对于 Emacs 或 Vim 等纯文本工具,你需要键入选择,而不是从菜单中选择,但最终结果仍然是相同的。

何时做变基

知道 何时 做变基与知道 如何 做变基同样重要。事实上,如果你不在乎你的仓库历史提交消息有点混乱的话,那么你可以永远都不使用 git rebase 命令。但是,如果你想要更干净的历史提交消息,并且想要更少扰乱你的图形视图的提交,那么当你使用 git rebase 命令时,有一个重要的经验法则需要时刻记住:

“不要变基你存储库以外的的提交,那些提交可能是别人工作的基础。”

如果你遵循该准则,不会发生什么大问题的。

简而言之,如果你让一个本地分支来完成你的工作,变基是没有问题的。但一旦该分支被 推送 push 了,就不要再变基该分支了。当然,你想要怎么做完全取决于你自己。

希望你会认为上述内容有助于你理解 git rebase 命令的工作原理,并能让你更有信心地使用它。与任何 Git 命令一样,练习是学习和理解怎么做的唯一方法。我鼓励你勇敢地尝试 交互式变基 interactive rebase git rebase -i <branch name>

接下来学习 Git cherry-pick 命令吧

大多数开发人员将修改提交到某一分支上,但是之后发现他们一直提交到了错误的分支上。理想情况下,他们可以拿走那个提交,然后把它移到正确的分支,这正是 git cherry-pick 命令的作用。

git cherry-pick 命令利用了变基单个提交的方法。这一用法非常常见,以至于有了它自己的命令。

Image of a woman picking a cherry from one tree and putting on another tree.

要使用 git cherry-pick,你只需告诉 Git 你要移动到“那个分支”的提交 ID(由 HEAD 指向):

$ git cherry-pick <target-ref>

如果出现问题,你可以根据 Git 提供的错误消息,来进行恢复:

$ git cherry-pick -i 2bc01cd
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: could not apply 2bc01cd… added EOF lines
hint: After resolving the conflicts, mark them with
hint: "git add/rm ", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
$ git cherry-pick --abort

让 Git 更强大

git rebase 命令是 Git 实用程序强大的地方之一。你最好在测试仓库中先练习一下怎么使用,一旦你熟悉了它的概念和工作流程,你就可以给仓库一个清晰历史消息记录了。


via: https://opensource.com/article/22/11/advanced-git-commands

作者:Dwayne McDaniel 选题:lkxed 译者:chai001125 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

参数对于交互式计算至关重要,Lua 编程语言提供了 {...} 表达式来封装在启动 Lua 脚本时给定的可变参数。

大多数计算机命令由两部分组成:命令和参数。命令是要执行的程序,而参数可能是命令选项或用户输入。如果没有这种结构,用户将不得不编辑命令的代码,以改变命令所处理的数据。想象一下重写 printf 命令只是为了让你的计算机用 “hello world” 消息问候你。参数对于交互式计算至关重要,Lua 编程语言 提供了 {...} 表达式来封装在启动 Lua 脚本时给定的可变参数。

在 Lua 中使用参数

几乎每一个给计算机的命令都假定一个参数,即使它期望参数是一个空列表。 Lua 会记录启动后写入的内容,即使你可能对这些参数不做任何操作。要在 Lua 启动时使用用户提供的参数,请迭代 {...} 表:

local args = {...}

for i,v in ipairs(args) do
    print(v)
end

运行代码:

$ lua ./myargs.lua
$ lua ./myargs.lua foo --bar baz
foo
--bar
baz
----

参数是不安全的,Lua 会完全按照输入的方式打印所有参数。

解析参数

对于简单的命令,Lua 的基本功能足以解析和处理参数。这是一个简单的例子:

-- setup

local args = {...}

-- engine

function echo(p)
   print(p)
end

-- go

for i,v in ipairs(args) do
  print(i .. ": " .. v)
end

for i,v in ipairs(args) do
  if args[i] == "--say" then
    echo("echo: " .. args[i+1])
  end
end

setup 部分,将所有命令参数转储到名为 args 的变量中。

engine 部分,创建一个名为 echo 的函数,用于打印你“输入”其中的任何内容。

最后,在 go 部分,解析 args 变量(用户在启动时提供的参数)中的索引和值。在此示例代码中,为清楚起见,第一个 for 循环仅打印每个索引和值。

第二个 for 循环使用索引来检查第一个参数,它被假定是一个选项。此示例代码中唯一有效的选项是 --say。如果循环找到字符串 --say,它会调用 echo 函数,并将当前参数的索引 加 1下一个 参数)作为函数参数提供。

命令参数的分隔符是一个或多个空格。运行代码查看结果:

$ lua ./echo.lua --say zombie apocalypse
1: --say
2: zombie
3: apocalypse
echo: zombie

大多数用户都知道在向计算机发出命令时空格很重要,因此在这种情况下删除第三个参数是预期的行为。下面是演示两种有效“转义”方法的变体:

$ lua ./echo.lua --say "zombie apocalypse"
1: --say
2: zombie apocalypse
echo: zombie apocalypse

$ lua ./echo.lua --say zombie\ apocalypse
1: --say
2: zombie apocalypse
echo: zombie apocalypse

解析参数

手动解析参数简单且无依赖性。但是,你必须考虑一些细节。大多数现代命令都允许使用短选项(例如,-f)和长选项(--foo),并且大多数命令都提供 -h--help 或者在没有所需参数时显示帮助菜单。

使用 LuaRocks 可以轻松安装其他库。有一些非常好的工具,例如 alt-getopt,它们为解析参数提供了额外的基础设施。


via: https://opensource.com/article/22/11/lua-command-arguments

作者:Seth Kenlon 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出