Michael Rappazzo | ac6c561 | 2015-10-02 07:55:31 -0400 | [diff] [blame] | 1 | #ifndef WORKTREE_H |
| 2 | #define WORKTREE_H |
| 3 | |
Nguyễn Thái Ngọc Duy | d0c39a4 | 2017-08-23 19:36:59 +0700 | [diff] [blame] | 4 | #include "refs.h" |
| 5 | |
Nguyễn Thái Ngọc Duy | 4ddddc1 | 2018-01-24 16:53:51 +0700 | [diff] [blame] | 6 | struct strbuf; |
| 7 | |
Michael Rappazzo | 5193490 | 2015-10-08 13:01:03 -0400 | [diff] [blame] | 8 | struct worktree { |
| 9 | char *path; |
Nguyễn Thái Ngọc Duy | 69dfe3b | 2016-04-22 20:01:26 +0700 | [diff] [blame] | 10 | char *id; |
Nguyễn Thái Ngọc Duy | fa099d2 | 2017-04-24 17:01:23 +0700 | [diff] [blame] | 11 | char *head_ref; /* NULL if HEAD is broken or detached */ |
Nickolai Belakovski | d236f12 | 2018-10-29 23:24:09 -0700 | [diff] [blame] | 12 | char *lock_reason; /* private - use worktree_lock_reason */ |
Rafael Silva | fc0c7d5 | 2021-01-19 22:27:34 +0100 | [diff] [blame] | 13 | char *prune_reason; /* private - use worktree_prune_reason */ |
brian m. carlson | 0f05154 | 2017-10-15 22:07:08 +0000 | [diff] [blame] | 14 | struct object_id head_oid; |
Michael Rappazzo | 92718b7 | 2015-10-08 13:01:04 -0400 | [diff] [blame] | 15 | int is_detached; |
| 16 | int is_bare; |
Nguyễn Thái Ngọc Duy | 750e8a6 | 2016-04-22 20:01:28 +0700 | [diff] [blame] | 17 | int is_current; |
Nickolai Belakovski | e21cc07 | 2018-10-29 23:24:08 -0700 | [diff] [blame] | 18 | int lock_reason_valid; /* private */ |
Rafael Silva | fc0c7d5 | 2021-01-19 22:27:34 +0100 | [diff] [blame] | 19 | int prune_reason_valid; /* private */ |
Michael Rappazzo | 5193490 | 2015-10-08 13:01:03 -0400 | [diff] [blame] | 20 | }; |
| 21 | |
Michael Rappazzo | 5193490 | 2015-10-08 13:01:03 -0400 | [diff] [blame] | 22 | /* |
| 23 | * Get the worktrees. The primary worktree will always be the first returned, |
Eric Sunshine | d9c54c2 | 2020-06-19 19:35:43 -0400 | [diff] [blame] | 24 | * and linked worktrees will follow in no particular order. |
Michael Rappazzo | 5193490 | 2015-10-08 13:01:03 -0400 | [diff] [blame] | 25 | * |
| 26 | * The caller is responsible for freeing the memory from the returned |
Eric Sunshine | d9c54c2 | 2020-06-19 19:35:43 -0400 | [diff] [blame] | 27 | * worktrees by calling free_worktrees(). |
Michael Rappazzo | 5193490 | 2015-10-08 13:01:03 -0400 | [diff] [blame] | 28 | */ |
Eric Sunshine | 03f2465 | 2020-06-19 19:35:44 -0400 | [diff] [blame] | 29 | struct worktree **get_worktrees(void); |
Michael Rappazzo | 5193490 | 2015-10-08 13:01:03 -0400 | [diff] [blame] | 30 | |
| 31 | /* |
Stefan Beller | 1a248cf | 2016-12-12 11:04:33 -0800 | [diff] [blame] | 32 | * Returns 1 if linked worktrees exist, 0 otherwise. |
| 33 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 34 | int submodule_uses_worktrees(const char *path); |
Stefan Beller | 1a248cf | 2016-12-12 11:04:33 -0800 | [diff] [blame] | 35 | |
| 36 | /* |
Nguyễn Thái Ngọc Duy | 69dfe3b | 2016-04-22 20:01:26 +0700 | [diff] [blame] | 37 | * Return git dir of the worktree. Note that the path may be relative. |
| 38 | * If wt is NULL, git dir of current worktree is returned. |
| 39 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 40 | const char *get_worktree_git_dir(const struct worktree *wt); |
Nguyễn Thái Ngọc Duy | 69dfe3b | 2016-04-22 20:01:26 +0700 | [diff] [blame] | 41 | |
| 42 | /* |
Eric Sunshine | a80c4c2 | 2020-02-24 04:08:46 -0500 | [diff] [blame] | 43 | * Search for the worktree identified unambiguously by `arg` -- typically |
| 44 | * supplied by the user via the command-line -- which may be a pathname or some |
| 45 | * shorthand uniquely identifying a worktree, thus making it convenient for the |
| 46 | * user to specify a worktree with minimal typing. For instance, if the last |
| 47 | * component (say, "foo") of a worktree's pathname is unique among worktrees |
| 48 | * (say, "work/foo" and "work/bar"), it can be used to identify the worktree |
| 49 | * unambiguously. |
| 50 | * |
| 51 | * `prefix` should be the `prefix` handed to top-level Git commands along with |
| 52 | * `argc` and `argv`. |
| 53 | * |
| 54 | * Return the worktree identified by `arg`, or NULL if not found. |
Nguyễn Thái Ngọc Duy | 6835314 | 2016-06-03 19:19:39 +0700 | [diff] [blame] | 55 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 56 | struct worktree *find_worktree(struct worktree **list, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 57 | const char *prefix, |
| 58 | const char *arg); |
Nguyễn Thái Ngọc Duy | 6835314 | 2016-06-03 19:19:39 +0700 | [diff] [blame] | 59 | |
| 60 | /* |
Eric Sunshine | bb4995f | 2020-02-24 04:08:47 -0500 | [diff] [blame] | 61 | * Return the worktree corresponding to `path`, or NULL if no such worktree |
| 62 | * exists. |
| 63 | */ |
| 64 | struct worktree *find_worktree_by_path(struct worktree **, const char *path); |
| 65 | |
| 66 | /* |
Nguyễn Thái Ngọc Duy | 984ad9e | 2016-06-03 19:19:40 +0700 | [diff] [blame] | 67 | * Return true if the given worktree is the main one. |
| 68 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 69 | int is_main_worktree(const struct worktree *wt); |
Nguyễn Thái Ngọc Duy | 984ad9e | 2016-06-03 19:19:40 +0700 | [diff] [blame] | 70 | |
| 71 | /* |
Nguyễn Thái Ngọc Duy | 346ef53 | 2016-06-13 19:18:23 +0700 | [diff] [blame] | 72 | * Return the reason string if the given worktree is locked or NULL |
| 73 | * otherwise. |
| 74 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 75 | const char *worktree_lock_reason(struct worktree *wt); |
Nguyễn Thái Ngọc Duy | 346ef53 | 2016-06-13 19:18:23 +0700 | [diff] [blame] | 76 | |
Rafael Silva | a29a8b7 | 2021-01-19 22:27:33 +0100 | [diff] [blame] | 77 | /* |
Rafael Silva | fc0c7d5 | 2021-01-19 22:27:34 +0100 | [diff] [blame] | 78 | * Return the reason string if the given worktree should be pruned, otherwise |
| 79 | * NULL if it should not be pruned. `expire` defines a grace period to prune |
| 80 | * the worktree when its path does not exist. |
| 81 | */ |
| 82 | const char *worktree_prune_reason(struct worktree *wt, timestamp_t expire); |
| 83 | |
| 84 | /* |
Rafael Silva | a29a8b7 | 2021-01-19 22:27:33 +0100 | [diff] [blame] | 85 | * Return true if worktree entry should be pruned, along with the reason for |
| 86 | * pruning. Otherwise, return false and the worktree's path in `wtpath`, or |
| 87 | * NULL if it cannot be determined. Caller is responsible for freeing |
| 88 | * returned path. |
| 89 | * |
| 90 | * `expire` defines a grace period to prune the worktree when its path |
| 91 | * does not exist. |
| 92 | */ |
| 93 | int should_prune_worktree(const char *id, |
| 94 | struct strbuf *reason, |
| 95 | char **wtpath, |
| 96 | timestamp_t expire); |
| 97 | |
Nguyễn Thái Ngọc Duy | ee6763a | 2018-02-12 16:49:40 +0700 | [diff] [blame] | 98 | #define WT_VALIDATE_WORKTREE_MISSING_OK (1 << 0) |
| 99 | |
Nguyễn Thái Ngọc Duy | 346ef53 | 2016-06-13 19:18:23 +0700 | [diff] [blame] | 100 | /* |
Nguyễn Thái Ngọc Duy | 4ddddc1 | 2018-01-24 16:53:51 +0700 | [diff] [blame] | 101 | * Return zero if the worktree is in good condition. Error message is |
| 102 | * returned if "errmsg" is not NULL. |
| 103 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 104 | int validate_worktree(const struct worktree *wt, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 105 | struct strbuf *errmsg, |
| 106 | unsigned flags); |
Nguyễn Thái Ngọc Duy | 4ddddc1 | 2018-01-24 16:53:51 +0700 | [diff] [blame] | 107 | |
| 108 | /* |
Nguyễn Thái Ngọc Duy | 9c620fc | 2018-02-12 16:49:35 +0700 | [diff] [blame] | 109 | * Update worktrees/xxx/gitdir with the new path. |
| 110 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 111 | void update_worktree_location(struct worktree *wt, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 112 | const char *path_); |
Nguyễn Thái Ngọc Duy | 9c620fc | 2018-02-12 16:49:35 +0700 | [diff] [blame] | 113 | |
Eric Sunshine | bdd1f3e | 2020-08-31 02:57:57 -0400 | [diff] [blame] | 114 | typedef void (* worktree_repair_fn)(int iserr, const char *path, |
| 115 | const char *msg, void *cb_data); |
| 116 | |
| 117 | /* |
| 118 | * Visit each registered linked worktree and repair corruptions. For each |
| 119 | * repair made or error encountered while attempting a repair, the callback |
| 120 | * function, if non-NULL, is called with the path of the worktree and a |
| 121 | * description of the repair or error, along with the callback user-data. |
| 122 | */ |
| 123 | void repair_worktrees(worktree_repair_fn, void *cb_data); |
| 124 | |
Nguyễn Thái Ngọc Duy | 9c620fc | 2018-02-12 16:49:35 +0700 | [diff] [blame] | 125 | /* |
Eric Sunshine | b214ab5 | 2020-08-31 02:57:58 -0400 | [diff] [blame] | 126 | * Repair administrative files corresponding to the worktree at the given path. |
| 127 | * The worktree's .git file pointing at the repository must be intact for the |
| 128 | * repair to succeed. Useful for re-associating an orphaned worktree with the |
| 129 | * repository if the worktree has been moved manually (without using "git |
| 130 | * worktree move"). For each repair made or error encountered while attempting |
| 131 | * a repair, the callback function, if non-NULL, is called with the path of the |
| 132 | * worktree and a description of the repair or error, along with the callback |
| 133 | * user-data. |
| 134 | */ |
| 135 | void repair_worktree_at_path(const char *, worktree_repair_fn, void *cb_data); |
| 136 | |
| 137 | /* |
Michael Rappazzo | 5193490 | 2015-10-08 13:01:03 -0400 | [diff] [blame] | 138 | * Free up the memory for worktree(s) |
| 139 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 140 | void free_worktrees(struct worktree **); |
Michael Rappazzo | 5193490 | 2015-10-08 13:01:03 -0400 | [diff] [blame] | 141 | |
Michael Rappazzo | ac6c561 | 2015-10-02 07:55:31 -0400 | [diff] [blame] | 142 | /* |
| 143 | * Check if a per-worktree symref points to a ref in the main worktree |
Nguyễn Thái Ngọc Duy | d3b9ac0 | 2016-04-22 20:01:27 +0700 | [diff] [blame] | 144 | * or any linked worktree, and return the worktree that holds the ref, |
Anders Kaseorg | c8dd491 | 2021-12-01 14:15:43 -0800 | [diff] [blame] | 145 | * or NULL otherwise. |
Michael Rappazzo | ac6c561 | 2015-10-02 07:55:31 -0400 | [diff] [blame] | 146 | */ |
Anders Kaseorg | c8dd491 | 2021-12-01 14:15:43 -0800 | [diff] [blame] | 147 | const struct worktree *find_shared_symref(struct worktree **worktrees, |
| 148 | const char *symref, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 149 | const char *target); |
Michael Rappazzo | ac6c561 | 2015-10-02 07:55:31 -0400 | [diff] [blame] | 150 | |
Nguyễn Thái Ngọc Duy | d0c39a4 | 2017-08-23 19:36:59 +0700 | [diff] [blame] | 151 | /* |
Rubén Justo | 662078c | 2023-02-25 15:21:51 +0100 | [diff] [blame] | 152 | * Returns true if a symref points to a ref in a worktree. |
| 153 | */ |
| 154 | int is_shared_symref(const struct worktree *wt, |
| 155 | const char *symref, const char *target); |
| 156 | |
| 157 | /* |
Nguyễn Thái Ngọc Duy | d0c39a4 | 2017-08-23 19:36:59 +0700 | [diff] [blame] | 158 | * Similar to head_ref() for all HEADs _except_ one from the current |
| 159 | * worktree, which is covered by head_ref(). |
| 160 | */ |
| 161 | int other_head_refs(each_ref_fn fn, void *cb_data); |
| 162 | |
Nguyễn Thái Ngọc Duy | 14ace5b | 2016-04-22 20:01:36 +0700 | [diff] [blame] | 163 | int is_worktree_being_rebased(const struct worktree *wt, const char *target); |
| 164 | int is_worktree_being_bisected(const struct worktree *wt, const char *target); |
| 165 | |
Nguyễn Thái Ngọc Duy | 2e641d5 | 2016-04-22 20:01:29 +0700 | [diff] [blame] | 166 | /* |
| 167 | * Similar to git_path() but can produce paths for a specified |
| 168 | * worktree instead of current one |
| 169 | */ |
Denton Liu | b199d71 | 2019-04-29 04:28:20 -0400 | [diff] [blame] | 170 | const char *worktree_git_path(const struct worktree *wt, |
Denton Liu | ad6dad0 | 2019-04-29 04:28:23 -0400 | [diff] [blame] | 171 | const char *fmt, ...) |
Nguyễn Thái Ngọc Duy | 2e641d5 | 2016-04-22 20:01:29 +0700 | [diff] [blame] | 172 | __attribute__((format (printf, 2, 3))); |
| 173 | |
Nguyễn Thái Ngọc Duy | 3a3b9d8 | 2018-10-21 10:08:54 +0200 | [diff] [blame] | 174 | /* |
Nguyễn Thái Ngọc Duy | ab3e1f7 | 2018-10-21 10:08:56 +0200 | [diff] [blame] | 175 | * Return a refname suitable for access from the current ref store. |
| 176 | */ |
| 177 | void strbuf_worktree_ref(const struct worktree *wt, |
| 178 | struct strbuf *sb, |
| 179 | const char *refname); |
| 180 | |
Derrick Stolee | 615a84a | 2022-02-07 21:32:59 +0000 | [diff] [blame] | 181 | /** |
| 182 | * Enable worktree config for the first time. This will make the following |
| 183 | * adjustments: |
| 184 | * |
| 185 | * 1. Add extensions.worktreeConfig=true in the common config file. |
| 186 | * |
| 187 | * 2. If the common config file has a core.worktree value, then that value |
| 188 | * is moved to the main worktree's config.worktree file. |
| 189 | * |
| 190 | * 3. If the common config file has a core.bare enabled, then that value |
| 191 | * is moved to the main worktree's config.worktree file. |
| 192 | * |
| 193 | * If extensions.worktreeConfig is already true, then this method |
| 194 | * terminates early without any of the above steps. The existing config |
| 195 | * arrangement is assumed to be intentional. |
| 196 | * |
| 197 | * Returns 0 on success. Reports an error message and returns non-zero |
| 198 | * if any of these steps fail. |
| 199 | */ |
| 200 | int init_worktree_config(struct repository *r); |
| 201 | |
Michael Rappazzo | ac6c561 | 2015-10-02 07:55:31 -0400 | [diff] [blame] | 202 | #endif |