[ Pobierz całość w formacie PDF ]
.git/hooks directory and make them executable.You can distributethese hooks within the project or in a separate project, but there is no way to set them up automatically.To begin, you should check your commit message just before each commit is recorded, so you know the server won t rejectyour changes due to badly formatted commit messages.To do this, you can add the commit-msg hook.If you have it read themessage from the file passed as the first argument and compare that to the pattern, you can force Git to abort the commit ifthere is no match:#!/usr/bin/env rubymessage_file = ARGV[0]message = File.read(message_file)$regex = /\[ref: (\d+)\]/if !$regex.match(message)puts "[POLICY] Your message is not formatted correctly"exit 1end 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 commit -am 'test'[POLICY] Your message is not formatted correctlyNo commit was completed in that instance.However, if your message contains the proper pattern, Git allows you to commit:$ 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 containsa copy of the ACL file you used previously, then the following pre-commit script will enforce those constraints for you:#!/usr/bin/env ruby$user = ENV['USER']# [ insert acl_access_data method from above ]# only allows certain users to modify certain subdirectories in a projectdef check_directory_permsaccess = get_acl_access_data('.git/acl')files_modified = `git diff-index --cached --name-only HEAD`.split("\n")files_modified.each do |path|next if path.size == 0has_file_access = falseaccess[$user].each do |access_path|if !access_path || (path.index(access_path) == 0)has_file_access = trueendif !has_file_accessputs "[POLICY] You do not have access to push to #{path}"exit 1endendendcheck_directory_permsThis is roughly the same script as the server-side part, but with two important differences.First, the ACL file is in a differentplace, because this script runs from your working directory, not from your Git directory.You have to change the path to theACL file from thisaccess = 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-sidemethod looks at the log of commits, and, at this point, the commit hasn t been recorded yet, you must get your file listing fromthe staging area instead.Instead offiles_modified = `git log -1 --name-only --pretty=format:'' #{ref}`you have to usefiles_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 berunning locally as the same user you push as to the remote machine.If that is different, you must set the $user variablemanually.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 lesscommon.To get a reference that isn t a fast-forward, you either have to rebase past a commit you ve already pushed up or trypushing a different local branch up to the same remote branch.Because the server will tell you that you can t push a non-fast-forward anyway, and the hook prevents forced pushes, the onlyaccidental thing you can try to catch is rebasing commits that have already been pushed.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, itaborts the rebase:#!/usr/bin/env rubybase_branch = ARGV[0]if ARGV[1]topic_branch = ARGV[1]elsetopic_branch = "HEAD"endtarget_shas = `git rev-list #{base_branch}.#{topic_branch}`.split("\n")remote_refs = `git branch -r`.split("\n").map { |r| r.strip }target_shas.each do |sha|remote_refs.each do |remote_ref|shas_pushed = `git rev-list ^#{sha}^@ refs/remotes/#{remote_ref}`if shas_pushed.split("\n").include?(sha)puts "[POLICY] Commit #{sha} has already been pushed to #{remote_ref}"exit 1endendendThis script uses a syntax that wasn t covered in the Revision Selection section of Chapter 6.You get a list of commits thathave 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 lastcommit 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 afast-forward [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • przylepto3.keep.pl