Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[zh]Chapter7: Completed. [zh] Draft: Completed

  • Loading branch information...
commit 5702b5622d1bba2a9824c74877ee70b80d81f7c9 1 parent eb7f0bb
Daniel Duan authored
Showing with 19 additions and 19 deletions.
  1. +19 −19 zh/07-customizing-git/01-chapter7.markdown
38 zh/07-customizing-git/01-chapter7.markdown
View
@@ -757,13 +757,13 @@ update 脚本和 `pre-receive` 脚本十分类似。不同之处在于它会为
全在这了。从这里开始,只要 `update` 脚本存在并且可执行,我们的仓库永远都不会遭到回转或者包含不符合要求信息的提交内容,并且用户都被锁在了沙箱里面。
-### Client-Side Hooks ###
+### 客户端挂钩 ###
-The downside to this approach is the whining that will inevitably result when your users’ commit pushes are rejected. Having their carefully crafted work rejected at the last minute can be extremely frustrating and confusing; and furthermore, they will have to edit their history to correct it, which isn’t always for the faint of heart.
+这种手段的缺点在于用户推送内容遭到拒绝后几乎无法避免的抱怨。辛辛苦苦写成的代码在最后时刻惨遭拒绝是十分悲剧切具迷惑性的;更可怜的是他们不得不修改提交历史来解决问题,这怎么也算不上王道。
-The answer to this dilemma is to provide some client-side hooks that users can use to notify them when they’re doing something that the server is likely to reject. That way, they can correct any problems before committing and before those issues become more difficult to fix. Because hooks aren’t transferred with a clone of a project, you must distribute these scripts some other way and then have your users copy them to their `.git/hooks` directory and make them executable. You can distribute these hooks within the project or in a separate project, but there is no way to set them up automatically.
+逃离这种两难境地的法宝是给用户一些客户端的挂钩,在他们作出可能悲剧的事情的时候给以警告。然后呢,用户们就能在提交--问题变得更难修正之前解除隐患。由于挂钩本身不跟随克隆的项目副本分发,所以必须通过其他途径把这些挂钩分发到用户的 .git/hooks 目录并设为可执行文件。虽然可以在相同或单独的项目内 容里加入并分发它们,全自动的解决方案是不存在的。
-To begin, you should check your commit message just before each commit is recorded, so you know the server won’t reject your changes due to badly formatted commit messages. To do this, you can add the `commit-msg` hook. If you have it read the message from the file passed as the first argument and compare that to the pattern, you can force Git to abort the commit if there is no match:
+首先在记录提交内容之前确认服务器不会因为提交信息的格式不符合要求而拒绝用户作出的修改。这一点可以通过添加一个 commit-msg 挂钩来实现。该挂钩从它的第一个文件参数读取提交信息从而和规定格式进行比对,这样就可以命令 Git 放 弃比对失败地提交内容:
#!/usr/bin/env ruby
message_file = ARGV[0]
@@ -776,18 +776,18 @@ To begin, you should check your commit message just before each commit is record
exit 1
end
-If that script is in place (in `.git/hooks/commit-msg`) and executable, and you commit with a message that isn’t properly formatted, you see this:
+如果这段脚本位置正确(在 .git/hooks/commit-msg)并切可执行,一次饱含错误信息格式的提交讲产生如下结果:
$ git commit -am 'test'
[POLICY] Your message is not formatted correctly
-No commit was completed in that instance. However, if your message contains the proper pattern, Git allows you to commit:
+这一次没有内容成功提交。然而一旦提交信息包含了正确格式的内容,Git 就允许提交:
$ git commit -am 'test [ref: 132]'
[master e05c914] test [ref: 132]
1 files changed, 1 insertions(+), 0 deletions(-)
-Next, you want to make sure you aren’t modifying files that are outside your ACL scope. If your project’s `.git` directory contains a copy of the ACL file you used previously, then the following `pre-commit` script will enforce those constraints for you:
+接下来我们要保证没有修改到 ACL 允许范围之外的文件。加入你的 .git 目录里有前面使用过的 ACL 文件,那么以下的 pre-commit 脚本将把里面的规定执行起来:
#!/usr/bin/env ruby
@@ -795,7 +795,7 @@ Next, you want to make sure you aren’t modifying files that are outside your A
# [ insert acl_access_data method from above ]
- # only allows certain users to modify certain subdirectories in a project
+ # 只允许特定用户修改项目重特定子目录的内容
def check_directory_perms
access = get_acl_access_data('.git/acl')
@@ -816,29 +816,29 @@ Next, you want to make sure you aren’t modifying files that are outside your A
check_directory_perms
-This is roughly the same script as the server-side part, but with two important differences. First, the ACL file is in a different place, because this script runs from your working directory, not from your Git directory. You have to change the path to the ACL file from this
+这和服务端的脚本几乎一样,除了两个重要区别。第一,ACL 文件的位置不同,因为这个脚本在当前工作目录运行,而非 Git 目录。ACL 文件的目录必须从
access = get_acl_access_data('acl')
-to this:
+修改成:
access = get_acl_access_data('.git/acl')
-The other important difference is the way you get a listing of the files that have been changed. Because the server-side method looks at the log of commits, and, at this point, the commit hasn’t been recorded yet, you must get your file listing from the staging area instead. Instead of
+另一个重要区别是获取被修改文件列表的方式。在服务端的时候使用了查看提交纪录的方式,可是目前的提交都还没被记录下来呢,所以这个列表只能从暂存区域获取。和原来的
files_modified = `git log -1 --name-only --pretty=format:'' #{ref}`
-you have to use
+不同,现在要用
files_modified = `git diff-index --cached --name-only HEAD`
-But those are the only two differences — otherwise, the script works the same way. One caveat is that it expects you to be running locally as the same user you push as to the remote machine. If that is different, you must set the `$user` variable manually.
+不同的就只有这两点——除此之外,该脚本完全相同。一个小陷阱在于它假设在本地运行的账户和推送到远程服务端的相同。如果这二者不一样,则需要手动设置一下 `$user` 变量。
-The last thing you have to do is check that you’re not trying to push non-fast-forwarded references, but that is a bit less common. To get a reference that isn’t a fast-forward, you either have to rebase past a commit you’ve already pushed up or try pushing a different local branch up to the same remote branch.
+最后一项任务是检查确认推送内容中不包含非 fast-forward 类型的索引,不过这个需求比较少见。要找出一个非 fast-forward 类型的索引,要么衍合超过某个已经推送过的提交,要么从本地不同分支推送到远程相同的分支上。
-Because the server will tell you that you can’t push a non-fast-forward anyway, and the hook prevents forced pushes, the only accidental thing you can try to catch is rebasing commits that have already been pushed.
+既然服务器将给出无法推送非 fast-forward 内容的提示,而且上面的挂钩也能阻止强制的推送,唯一剩下的潜在问题就是衍合一次已经推送过的提交内容。
-Here is an example pre-rebase script that checks for that. It gets a list of all the commits you’re about to rewrite and checks whether they exist in any of your remote references. If it sees one that is reachable from one of your remote references, it aborts the rebase:
+下面是一个检查这个问题的 pre-rabase 脚本的例子。它获取一个所有即将重写的提交内容的列表,然后检查它们是否在远程的索引里已经存在。一旦发现某个提交可以从远程索引里衍变过来,它就放弃衍合操作:
#!/usr/bin/env ruby
@@ -862,13 +862,13 @@ Here is an example pre-rebase script that checks for that. It gets a list of all
end
end
-This script uses a syntax that wasn’t covered in the Revision Selection section of Chapter 6. You get a list of commits that have already been pushed up by running this:
+这个脚本利用了一个第六章“修订版本选择”一节中不曾提到的语法。通过这一句可以获得一个所有已经完成推送的提交的列表:
git rev-list ^#{sha}^@ refs/remotes/#{remote_ref}
-The `SHA^@` syntax resolves to all the parents of that commit. You’re looking for any commit that is reachable from the last commit on the remote and that isn’t reachable from any parent of any of the SHAs you’re trying to push up — meaning it’s a fast-forward.
+`SHA^@` 语法解析该次提交的所有祖先。这里我们从检查远程最后一次提交能够衍变获得但从所有我们尝试推送的提交的 SHA 值祖先无法衍变获得的提交内容——也就是 fast-forward 的内容。
-The main drawback to this approach is that it can be very slow and is often unnecessary — if you don’t try to force the push with `-f`, the server will warn you and not accept the push. However, it’s an interesting exercise and can in theory help you avoid a rebase that you might later have to go back and fix.
+这个解决方案的硬伤在于它有可能很慢而且常常没有必要——只要不用 `-f` 来强制推送,服务器会自动给出警告并且拒绝推送内容。然而,这是个不错的练习而且理论上能帮助用户避免一次将来不得不折回来修改的衍合操作。
## 总结 ##
Please sign in to comment.
Something went wrong with that request. Please try again.