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) 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/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 ============================================================ 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/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/ 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/