1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
70
  
71
  
72
  
73
  
74
  
75
  
76
  
77
  
78
  
79
  
80
  
81
  
82
  
83
  
84
  
85
  
86
  
87
  
88
  
89
  
90
  
91
  
92
  
93
  
94
  
95
  
96
  
97
  
98
  
99
  
100
  
101
  
102
  
103
  
104
  
105
  
106
  
107
  
108
  
109
  
110
  
111
  
112
  
113
  
114
  
115
  
116
  
117
  
118
  
119
  
120
  
121
  
122
  
123
  
124
  
125
  
126
  
127
  
128
  
129
  
130
  
131
  
132
  
133
  
134
  
135
  
#pike __REAL_VERSION__ 
 
//! This is a module for interacting with the Git 
//! distributed version control system. 
 
//! The git binary to use. 
//! 
//! Defaults to @expr{"git"@}, but may be overridden 
//! to select a different binary. 
string git_binary = "git"; 
 
//! A normal (non-executable) file. 
constant MODE_FILE = 0100644; 
 
//! A normal, but executable file. 
constant MODE_EXE = 0100755; 
 
//! A symbolic link. 
constant MODE_SYMLINK = 0120000; 
 
//! A gitlink (aka submodule reference). 
constant MODE_GITLINK = 0160000; 
 
//! A subdirectory. 
constant MODE_DIR = 040000; 
 
//! The NULL SHA1. 
constant NULL_SHA1 = "0000000000000000000000000000000000000000"; 
 
//! Start a git process. 
//! 
//! @param options 
//!   Options for @[Process.Process()]. 
//! 
//! @param git_dir 
//!   Directory containing the Git repository. May be @expr{UNDEFINED@} 
//!   to specify the Git repository for the current directory. 
//! 
//! @param command 
//!   Git subcommand to execute. 
//! 
//! @param args 
//!   Arguemnts for @[command]. 
//! 
//! @returns 
//!   Returns the corresponding @[Process.Process] object. 
//! 
//! @seealso 
//!   @[git()], @[try_git()] 
Process.Process low_git(mapping(string:mixed) options, 
                        string git_dir, string command, string ... args) 
{ 
  if (git_dir) { 
    return Process.Process(({ git_binary, "--git-dir", git_dir, 
                              command, @args }), options); 
  } 
  return Process.Process(({ git_binary, command, @args }), options); 
} 
 
//! Run a git command, and get the output. 
//! 
//! @param git_dir 
//!   Directory containing the Git repository. May be @expr{UNDEFINED@} 
//!   to specify the Git repository for the current directory. 
//! 
//! @param command 
//!   Git subcommand to execute. 
//! 
//! @param args 
//!   Arguemnts for @[command]. 
//! 
//! @returns 
//!   Returns the output on @tt{stdout@} from running the command 
//!   on success, and throws an error on failure. 
//! 
//! @seealso 
//!   @[try_git()], @[low_git()] 
string git(string git_dir, string command, string ... args) 
{ 
  array(string) cmd; 
  if (git_dir) { 
    cmd = ({ git_binary, "--git-dir", git_dir, command, @args }); 
  } else { 
    cmd = ({ git_binary, command, @args }); 
  } 
  mapping(string:string|int) res = Process.run(cmd); 
  if (res->exitcode) { 
    werror("CWD: %O\n", getcwd()); 
    error("Git command '%s' failed with code %d:\n" 
          "%s", cmd*"' '", res->exitcode, res->stderr||""); 
  } 
  return res->stdout||""; 
} 
 
//! Attempt to run a git command and get its output. 
//! 
//! @param git_dir 
//!   Directory containing the Git repository. May be @expr{UNDEFINED@} 
//!   to specify the Git repository for the current directory. 
//! 
//! @param command 
//!   Git subcommand to execute. 
//! 
//! @param args 
//!   Arguemnts for @[command]. 
//! 
//! @returns 
//!   Returns the output on @tt{stdout@} from running the command 
//!   on success, and @expr{0@} (zero) on failure. 
//! 
//! @note 
//!   This is a convenience function, and there is no way to get 
//!   the specific cause for failures other than rerunning the 
//!   command with e.g. @[git()]. 
//! 
//! @seealso 
//!   @[git()], @[low_git()] 
string try_git(string git_dir, string command, string ... args) 
{ 
  mixed err = catch { 
      return git(git_dir, command, @args); 
    }; 
  return 0; 
} 
 
//! Hash algorithm for blobs that is compatible with git. 
string hash_blob(string data) 
{ 
  Crypto.SHA1 sha1 = Crypto.SHA1(); 
  sha1->update(sprintf("blob %d\0", sizeof(data))); 
  sha1->update(data); 
  return String.string2hex(sha1->digest()); 
}