Skip to content

Commit 63dfa6e

Browse files
committed
Merge branch 'scalar'
This merges the upstreamable part of the Scalar patches. Minor merge conflicts (caused by the gvfs-helper) were resolved trivially. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2 parents f20b0a4 + 4a09510 commit 63dfa6e

File tree

8 files changed

+332
-6
lines changed

8 files changed

+332
-6
lines changed

Diff for: Documentation/config/core.txt

+9
Original file line numberDiff line numberDiff line change
@@ -834,3 +834,12 @@ core.WSLCompat::
834834
The default value is false. When set to true, Git will set the mode
835835
bits of the file in the way of wsl, so that the executable flag of
836836
files can be set or read correctly.
837+
838+
core.configWriteLockTimeoutMS::
839+
When processes try to write to the config concurrently, it is likely
840+
that one process "wins" and the other process(es) fail to lock the
841+
config file. By configuring a timeout larger than zero, Git can be
842+
told to try to lock the config again a couple times within the
843+
specified timeout. If the timeout is configure to zero (which is the
844+
default), Git will fail immediately when the config is already
845+
locked.

Diff for: config.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -3275,6 +3275,7 @@ int repo_config_set_multivar_in_file_gently(struct repository *r,
32753275
const char *comment,
32763276
unsigned flags)
32773277
{
3278+
static unsigned long timeout_ms = ULONG_MAX;
32783279
int fd = -1, in_fd = -1;
32793280
int ret;
32803281
struct lock_file lock = LOCK_INIT;
@@ -3295,11 +3296,16 @@ int repo_config_set_multivar_in_file_gently(struct repository *r,
32953296
if (!config_filename)
32963297
config_filename = filename_buf = repo_git_path(r, "config");
32973298

3299+
if ((long)timeout_ms < 0 &&
3300+
git_config_get_ulong("core.configWriteLockTimeoutMS", &timeout_ms))
3301+
timeout_ms = 0;
3302+
32983303
/*
32993304
* The lock serves a purpose in addition to locking: the new
33003305
* contents of .git/config will be written into it.
33013306
*/
3302-
fd = hold_lock_file_for_update(&lock, config_filename, 0);
3307+
fd = hold_lock_file_for_update_timeout(&lock, config_filename, 0,
3308+
timeout_ms);
33033309
if (fd < 0) {
33043310
error_errno(_("could not lock config file %s"), config_filename);
33053311
ret = CONFIG_NO_LOCK;

Diff for: contrib/scalar/docs/faq.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
Frequently Asked Questions
2+
==========================
3+
4+
Using Scalar
5+
------------
6+
7+
### I don't want a sparse clone, I want every file after I clone!
8+
9+
Run `scalar clone --full-clone <url>` to initialize your repo to include
10+
every file. You can switch to a sparse-checkout later by running
11+
`git sparse-checkout init --cone`.
12+
13+
### I already cloned without `--full-clone`. How do I get everything?
14+
15+
Run `git sparse-checkout disable`.
16+
17+
Scalar Design Decisions
18+
-----------------------
19+
20+
There may be many design decisions within Scalar that are confusing at first
21+
glance. Some of them may cause friction when you use Scalar with your existing
22+
repos and existing habits.
23+
24+
> Scalar has the most benefit when users design repositories
25+
> with efficient patterns.
26+
27+
For example: Scalar uses the sparse-checkout feature to limit the size of the
28+
working directory within a large monorepo. It is designed to work efficiently
29+
with monorepos that are highly componentized, allowing most developers to
30+
need many fewer files in their daily work.
31+
32+
### Why does `scalar clone` create a `<repo>/src` folder?
33+
34+
Scalar uses a file system watcher to keep track of changes under this `src` folder.
35+
Any activity in this folder is assumed to be important to Git operations. By
36+
creating the `src` folder, we are making it easy for your build system to
37+
create output folders outside the `src` directory. We commonly see systems
38+
create folders for build outputs and package downloads. Scalar itself creates
39+
these folders during its builds.
40+
41+
Your build system may create build artifacts such as `.obj` or `.lib` files
42+
next to your source code. These are commonly "hidden" from Git using
43+
`.gitignore` files. Having such artifacts in your source tree creates
44+
additional work for Git because it needs to look at these files and match them
45+
against the `.gitignore` patterns.
46+
47+
By following the `src` pattern Scalar tries to establish and placing your build
48+
intermediates and outputs parallel with the `src` folder and not inside it,
49+
you can help optimize Git command performance for developers in the repository
50+
by limiting the number of files Git needs to consider for many common
51+
operations.

Diff for: contrib/scalar/docs/getting-started.md

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
Getting Started
2+
===============
3+
4+
Registering existing Git repos
5+
------------------------------
6+
7+
To add a repository to the list of registered repos, run `scalar register [<path>]`.
8+
If `<path>` is not provided, then the "current repository" is discovered from
9+
the working directory by scanning the parent paths for a path containing a `.git`
10+
folder, possibly inside a `src` folder.
11+
12+
To see which repositories are currently tracked by the service, run
13+
`scalar list`.
14+
15+
Run `scalar unregister [<path>]` to remove the repo from this list.
16+
17+
Creating a new Scalar clone
18+
---------------------------------------------------
19+
20+
The `clone` verb creates a local enlistment of a remote repository using the
21+
partial clone feature available e.g. on GitHub.
22+
23+
24+
```
25+
scalar clone [options] <url> [<dir>]
26+
```
27+
28+
Create a local copy of the repository at `<url>`. If specified, create the `<dir>`
29+
directory and place the repository there. Otherwise, the last section of the `<url>`
30+
will be used for `<dir>`.
31+
32+
At the end, the repo is located at `<dir>/src`. By default, the sparse-checkout
33+
feature is enabled and the only files present are those in the root of your
34+
Git repository. Use `git sparse-checkout set` to expand the set of directories
35+
you want to see, or `git sparse-checkout disable` to expand to all files. You
36+
can explore the subdirectories outside your sparse-checkout specification using
37+
`git ls-tree HEAD`.
38+
39+
### Sparse Repo Mode
40+
41+
By default, Scalar reduces your working directory to only the files at the
42+
root of the repository. You need to add the folders you care about to build up
43+
to your working set.
44+
45+
* `scalar clone <url>`
46+
* Please choose the **Clone with HTTPS** option in the `Clone Repository` dialog in Azure Repos, not **Clone with SSH**.
47+
* `cd <root>\src`
48+
* At this point, your `src` directory only contains files that appear in your root
49+
tree. No folders are populated.
50+
* Set the directory list for your sparse-checkout using:
51+
1. `git sparse-checkout set <dir1> <dir2> ...`
52+
2. `git sparse-checkout set --stdin < dir-list.txt`
53+
* Run git commands as you normally would.
54+
* To fully populate your working directory, run `git sparse-checkout disable`.
55+
56+
If instead you want to start with all files on-disk, you can clone with the
57+
`--full-clone` option. To enable sparse-checkout after the fact, run
58+
`git sparse-checkout init --cone`. This will initialize your sparse-checkout
59+
patterns to only match the files at root.
60+
61+
If you are unfamiliar with what directories are available in the repository,
62+
then you can run `git ls-tree -d --name-only HEAD` to discover the directories
63+
at root, or `git ls-tree -d --name-only HEAD <path>` to discover the directories
64+
in `<path>`.
65+
66+
### Options
67+
68+
These options allow a user to customize their initial enlistment.
69+
70+
* `--full-clone`: If specified, do not initialize the sparse-checkout feature.
71+
All files will be present in your `src` directory. This uses a Git partial
72+
clone: blobs are downloaded on demand.
73+
74+
* `--branch=<ref>`: Specify the branch to checkout after clone.
75+
76+
### Advanced Options
77+
78+
The options below are not intended for use by a typical user. These are
79+
usually used by build machines to create a temporary enlistment that
80+
operates on a single commit.
81+
82+
* `--single-branch`: Use this option to only download metadata for the branch
83+
that will be checked out. This is helpful for build machines that target
84+
a remote with many branches. Any `git fetch` commands after the clone will
85+
still ask for all branches.
86+
87+
Removing a Scalar Clone
88+
-----------------------
89+
90+
Since the `scalar clone` command sets up a file-system watcher (when available),
91+
that watcher could prevent deleting the enlistment. Run `scalar delete <path>`
92+
from outside of your enlistment to unregister the enlistment from the filesystem
93+
watcher and delete the enlistment at `<path>`.

Diff for: contrib/scalar/docs/index.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
Scalar: Enabling Git at Scale
2+
=============================
3+
4+
Scalar is a tool that helps Git scale to some of the largest Git repositories.
5+
It achieves this by enabling some advanced Git features, such as:
6+
7+
* *Partial clone:* reduces time to get a working repository by not
8+
downloading all Git objects right away.
9+
10+
* *Background prefetch:* downloads Git object data from all remotes every
11+
hour, reducing the amount of time for foreground `git fetch` calls.
12+
13+
* *Sparse-checkout:* limits the size of your working directory.
14+
15+
* *File system monitor:* tracks the recently modified files and eliminates
16+
the need for Git to scan the entire worktree.
17+
18+
* *Commit-graph:* accelerates commit walks and reachability calculations,
19+
speeding up commands like `git log`.
20+
21+
* *Multi-pack-index:* enables fast object lookups across many pack-files.
22+
23+
* *Incremental repack:* Repacks the packed Git data into fewer pack-file
24+
without disrupting concurrent commands by using the multi-pack-index.
25+
26+
By running `scalar register` in any Git repo, Scalar will automatically enable
27+
these features for that repo (except partial clone) and start running suggested
28+
maintenance in the background using
29+
[the `git maintenance` feature](https://git-scm.com/docs/git-maintenance).
30+
31+
Repos cloned with the `scalar clone` command use partial clone to significantly
32+
reduce the amount of data required to get started using a repository. By
33+
delaying all blob downloads until they are required, Scalar allows you to work
34+
with very large repositories quickly.
35+
36+
Documentation
37+
-------------
38+
39+
* [Getting Started](getting-started.md): Get started with Scalar.
40+
Includes `scalar register`, `scalar unregister`, `scalar clone`, and
41+
`scalar delete`.
42+
43+
* [Troubleshooting](troubleshooting.md):
44+
Collect diagnostic information or update custom settings. Includes
45+
`scalar diagnose`.
46+
47+
* [The Philosophy of Scalar](philosophy.md): Why does Scalar work the way
48+
it does, and how do we make decisions about its future?
49+
50+
* [Frequently Asked Questions](faq.md)

Diff for: contrib/scalar/docs/philosophy.md

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
The Philosophy of Scalar
2+
========================
3+
4+
The team building Scalar has **opinions** about Git performance. Scalar
5+
takes out the guesswork by automatically configuring your Git repositories
6+
to take advantage of the latest and greatest features. It is difficult to
7+
say that these are the absolute best settings for every repository, but
8+
these settings do work for some of the largest repositories in the world.
9+
10+
Scalar intends to do very little more than the standard Git client. We
11+
actively implement new features into Git instead of Scalar, then update
12+
Scalar only to configure those new settings. In particular, we ported
13+
features like background maintenance to Git to make Scalar simpler and
14+
make Git more powerful.
15+
16+
Services such as GitHub support partial clone , a standard adopted by the Git
17+
project to download only part of the Git objects when cloning, and fetching
18+
further objects on demand. If your hosting service supports partial clone, then
19+
we absolutely recommend it as a way to greatly speed up your clone and fetch
20+
times and to reduce how much disk space your Git repository requires. Scalar
21+
will help with this!
22+
23+
Most of the value of Scalar can be found in the core Git client. However, most
24+
of the advanced features that really optimize Git's performance are off by
25+
default for compatibility reasons. To really take advantage of Git's latest and
26+
greatest features, you either need to study the [`git config`
27+
documentation](https://git-scm.com/docs/git-config) and regularly read [the Git
28+
release notes](https://github.com/git/git/tree/master/Documentation/RelNotes).
29+
Even if you do all that work and customize your Git settings on your machines,
30+
you likely will want to share those settings with other team members. Or, you
31+
can just use Scalar!
32+
33+
Using `scalar register` on an existing Git repository will give you these
34+
benefits:
35+
36+
* Additional compression of your `.git/index` file.
37+
* Hourly background `git fetch` operations, keeping you in-sync with your
38+
remotes.
39+
* Advanced data structures, such as the `commit-graph` and `multi-pack-index`
40+
are updated automatically in the background.
41+
* If using macOS or Windows, then Scalar configures Git's builtin File System
42+
Monitor, providing faster commands such as `git status` or `git add`.
43+
44+
Additionally, if you use `scalar clone` to create a new repository, then
45+
you will automatically get these benefits:
46+
47+
* Use Git's partial clone feature to only download the files you need for
48+
your current checkout.
49+
* Use Git's [sparse-checkout feature][sparse-checkout] to minimize the
50+
number of files required in your working directory.
51+
[Read more about sparse-checkout here.][sparse-checkout-blog]
52+
* Create the Git repository inside `<repo-name>/src` to make it easy to
53+
place build artifacts outside of the Git repository, such as in
54+
`<repo-name>/bin` or `<repo-name>/packages`.
55+
56+
We also admit that these **opinions** can always be improved! If you have
57+
an idea of how to improve our setup, consider
58+
[creating an issue](https://github.com/microsoft/scalar/issues/new) or
59+
contributing a pull request! Some [existing](https://github.com/microsoft/scalar/issues/382)
60+
[issues](https://github.com/microsoft/scalar/issues/388) have already
61+
improved our configuration settings and roadmap!
62+
63+
[gvfs-protocol]: https://github.com/microsoft/VFSForGit/blob/HEAD/Protocol.md
64+
[microsoft-git]: https://github.com/microsoft/git
65+
[sparse-checkout]: https://git-scm.com/docs/git-sparse-checkout
66+
[sparse-checkout-blog]: https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/

Diff for: contrib/scalar/docs/troubleshooting.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Troubleshooting
2+
===============
3+
4+
Diagnosing Issues
5+
-----------------
6+
7+
The `scalar diagnose` command collects logs and config details for the current
8+
repository. The resulting zip file helps root-cause issues.
9+
10+
When run inside your repository, creates a zip file containing several important
11+
files for that repository. This includes:
12+
13+
* Configuration files from your `.git` folder, such as the `config` file,
14+
`index`, `hooks`, and `refs`.
15+
16+
* A summary of your Git object database, including the number of loose objects
17+
and the names and sizes of pack-files.
18+
19+
As the `diagnose` command completes, it provides the path of the resulting
20+
zip file. This zip can be attached to bug reports to make the analysis easier.

0 commit comments

Comments
 (0)