[{"data":1,"prerenderedAt":3310},["ShallowReactive",2],{"/blog/whats-new-in-git-2-49-0":3,"navigation-en-us":2527,"banner-en-us":2953,"footer-en-us":2963,"blog-post-authors-en-us-Toon Claes":3208,"blog-related-posts-en-us-whats-new-in-git-2-49-0":3223,"blog-promotions-en-us":3246,"next-steps-en-us":3300},{"id":4,"title":5,"authors":6,"body":8,"category":2507,"date":2508,"description":2509,"extension":2510,"externalUrl":2511,"faq":2511,"featured":513,"heroImage":2512,"meta":2513,"navigation":513,"path":2514,"seo":2515,"slug":2520,"stem":2521,"tags":2522,"template":2525,"updatedDate":2511,"__hash__":2526},"blogPosts/en-us/blog/whats-new-in-git-2-49-0.md","What's new in Git 2.49.0?",[7],"Toon Claes",{"type":9,"value":10,"toc":2496},"minimark",[11,22,25,81,85,117,139,146,168,179,362,369,424,427,695,698,704,1232,1238,1555,1558,1607,1627,1630,1657,1671,1686,1707,1712,1721,1733,1845,1854,1865,1885,1888,1919,1922,1992,1998,2001,2026,2074,2094,2106,2109,2116,2133,2160,2165,2179,2182,2188,2206,2211,2231,2240,2311,2325,2328,2337,2351,2354,2364,2375,2378,2396,2401,2436,2446,2464,2469,2492],[12,13,14,15,21],"p",{},"The Git project recently released ",[16,17,20],"a",{"href":18,"rel":19},"https://lore.kernel.org/git/xmqqfrjfilc8.fsf@gitster.g/",[],"Git 2.49.0",". Let's look at a few notable highlights from this release, which includes contributions from GitLab's Git team and the wider Git community.",[12,23,24],{},"What's covered:",[26,27,28,35,41,47,53,59,65,71],"ul",{},[29,30,31],"li",{},[16,32,34],{"href":33},"#git-backfill(1)-and-the-new-path-walk-api","git-backfill(1) and the new path-walk API",[29,36,37],{},[16,38,40],{"href":39},"#introduction-of-zlib-ng","Introduction of zlib-ng",[29,42,43],{},[16,44,46],{"href":45},"#continued-iteration-on-meson","Continued iteration on Meson",[29,48,49],{},[16,50,52],{"href":51},"#deprecation-of-.gitbranches%2F-and-.git%2Fremotes%2F","Deprecation of .git/branches/ and .git/remotes/",[29,54,55],{},[16,56,58],{"href":57},"#rust-bindings-for-libgit","Rust bindings for libgit",[29,60,61],{},[16,62,64],{"href":63},"#new-name-hashing-algorithm","New name-hashing algorithm",[29,66,67],{},[16,68,70],{"href":69},"#promisor-remote-capability","Promisor remote capability",[29,72,73],{},[16,74,76,77],{"href":75},"#thin-clone-using---revision","Thin clone using ",[78,79,80],"code",{},"--revision",[82,83,34],"h2",{"id":84},"git-backfill1-and-the-new-path-walk-api",[12,86,87,88,95,96,103,104,108,109,112,113,116],{},"When you ",[16,89,92],{"href":90,"rel":91},"https://git-scm.com/docs/git-clone",[],[78,93,94],{},"git-clone(1)"," a Git repository,\nyou can pass it the\n",[16,97,100],{"href":98,"rel":99},"https://git-scm.com/docs/git-clone#Documentation/git-clone.txt-code--filterltfilter-specgtcode",[],[78,101,102],{},"--filter","\noption. Using this option allows you to create a ",[105,106,107],"em",{},"partial clone",". In a partial\nclone the server only sends a subset of reachable objects according to the given\nobject filter. For example, creating a clone with ",[78,110,111],{},"--filter=blob:none"," will not\nfetch any blobs (file contents) from the server and create a ",[105,114,115],{},"blobless clone",".",[12,118,119,120,127,128,135,136,138],{},"Blobless clones have all the reachable commits and trees, but no blobs. When you\nperform an operation like\n",[16,121,124],{"href":122,"rel":123},"https://git-scm.com/docs/git-checkout",[],[78,125,126],{},"git-checkout(1)",", Git will download\nthe missing blobs to complete that operation. For some operations, like\n",[16,129,132],{"href":130,"rel":131},"https://git-scm.com/docs/git-blame",[],[78,133,134],{},"git-blame(1)",", this might result in\ndownloading objects one by one, which will slow down the command drastically.\nThis performance degradation occurs because ",[78,137,134],{}," must traverse the\ncommit history to identify which specific blobs it needs, then request each\nmissing blob from the server separately.",[12,140,141,142,145],{},"In Git 2.49, a new subcommand ",[78,143,144],{},"git-backfill(1)"," is introduced, which can be\nused to download missing blobs in a blobless partial clone.",[12,147,148,149,151,152,155,156,159,160,163,164,167],{},"Under the hood, the ",[78,150,144],{}," command leverages the new path-walk API, which is different from how Git generally iterates over commits. Rather than iterating over the commits one at a time and recursively visiting the trees and blobs associated with each commit, the path-walk API does traversal by path. For each path, it adds a list of associated tree objects to a stack. This stack is then processed in a depth-first order. So, instead of processing every object in commit ",[78,153,154],{},"1"," before moving to commit ",[78,157,158],{},"2",", it will process all versions of file ",[78,161,162],{},"A"," across all commits before moving to file ",[78,165,166],{},"B",". This approach greatly improves performance in scenarios where grouping by path is essential.",[12,169,170,171,178],{},"Let me demonstrate its use by making a blobless clone of ",[16,172,175],{"href":173,"rel":174},"https://gitlab.com/gitlab-org/git",[],[78,176,177],{},"gitlab-org/git",":",[180,181,186],"pre",{"className":182,"code":183,"language":184,"meta":185,"style":185},"language-shell shiki shiki-themes github-light","$ git clone --filter=blob:none --bare --no-tags git@gitlab.com:gitlab-org/git.git\nCloning into bare repository 'git.git'...\nremote: Enumerating objects: 245904, done.\nremote: Counting objects: 100% (1736/1736), done.\nremote: Compressing objects: 100% (276/276), done.\nremote: Total 245904 (delta 1591), reused 1547 (delta 1459), pack-reused 244168 (from 1)\nReceiving objects: 100% (245904/245904), 59.35 MiB | 15.96 MiB/s, done.\nResolving deltas: 100% (161482/161482), done.\n","shell","",[78,187,188,217,235,253,270,285,323,348],{"__ignoreMap":185},[189,190,193,197,201,204,208,211,214],"span",{"class":191,"line":192},"line",1,[189,194,196],{"class":195},"s7eDp","$",[189,198,200],{"class":199},"sYBdl"," git",[189,202,203],{"class":199}," clone",[189,205,207],{"class":206},"sYu0t"," --filter=blob:none",[189,209,210],{"class":206}," --bare",[189,212,213],{"class":206}," --no-tags",[189,215,216],{"class":199}," git@gitlab.com:gitlab-org/git.git\n",[189,218,220,223,226,229,232],{"class":191,"line":219},2,[189,221,222],{"class":195},"Cloning",[189,224,225],{"class":199}," into",[189,227,228],{"class":199}," bare",[189,230,231],{"class":199}," repository",[189,233,234],{"class":199}," 'git.git'...\n",[189,236,238,241,244,247,250],{"class":191,"line":237},3,[189,239,240],{"class":195},"remote:",[189,242,243],{"class":199}," Enumerating",[189,245,246],{"class":199}," objects:",[189,248,249],{"class":199}," 245904,",[189,251,252],{"class":199}," done.\n",[189,254,256,258,261,263,266],{"class":191,"line":255},4,[189,257,240],{"class":195},[189,259,260],{"class":199}," Counting",[189,262,246],{"class":199},[189,264,265],{"class":199}," 100%",[189,267,269],{"class":268},"sgsFI"," (1736/1736), done.\n",[189,271,273,275,278,280,282],{"class":191,"line":272},5,[189,274,240],{"class":195},[189,276,277],{"class":199}," Compressing",[189,279,246],{"class":199},[189,281,265],{"class":199},[189,283,284],{"class":268}," (276/276), done.\n",[189,286,288,290,293,296,299,302,305,308,311,314,317,320],{"class":191,"line":287},6,[189,289,240],{"class":195},[189,291,292],{"class":199}," Total",[189,294,295],{"class":206}," 245904",[189,297,298],{"class":268}," (delta ",[189,300,301],{"class":206},"1591",[189,303,304],{"class":268},"), reused 1547 (",[189,306,307],{"class":195},"delta",[189,309,310],{"class":206}," 1459",[189,312,313],{"class":268},"), pack-reused 244168 (",[189,315,316],{"class":195},"from",[189,318,319],{"class":206}," 1",[189,321,322],{"class":268},")\n",[189,324,326,329,331,333,336,340,343,346],{"class":191,"line":325},7,[189,327,328],{"class":195},"Receiving",[189,330,246],{"class":199},[189,332,265],{"class":199},[189,334,335],{"class":268}," (245904/245904), 59.35 MiB ",[189,337,339],{"class":338},"sD7c4","|",[189,341,342],{"class":195}," 15.96",[189,344,345],{"class":199}," MiB/s,",[189,347,252],{"class":199},[189,349,351,354,357,359],{"class":191,"line":350},8,[189,352,353],{"class":195},"Resolving",[189,355,356],{"class":199}," deltas:",[189,358,265],{"class":199},[189,360,361],{"class":268}," (161482/161482), done.\n",[12,363,364,365,368],{},"Above, we use ",[78,366,367],{},"--bare"," to ensure Git doesn't need to download any blobs to check\nout an initial branch. We can verify this clone does not contain any blobs:",[180,370,374],{"className":371,"code":372,"language":373,"meta":185,"style":185},"language-sh shiki shiki-themes github-light","$ git cat-file --batch-all-objects --batch-check='%(objecttype)' | sort | uniq -c\n  83977 commit\n 161927 tree\n","sh",[78,375,376,408,416],{"__ignoreMap":185},[189,377,378,380,382,385,388,391,394,397,400,402,405],{"class":191,"line":192},[189,379,196],{"class":195},[189,381,200],{"class":199},[189,383,384],{"class":199}," cat-file",[189,386,387],{"class":206}," --batch-all-objects",[189,389,390],{"class":206}," --batch-check=",[189,392,393],{"class":199},"'%(objecttype)'",[189,395,396],{"class":338}," |",[189,398,399],{"class":195}," sort",[189,401,396],{"class":338},[189,403,404],{"class":195}," uniq",[189,406,407],{"class":206}," -c\n",[189,409,410,413],{"class":191,"line":219},[189,411,412],{"class":195},"  83977",[189,414,415],{"class":199}," commit\n",[189,417,418,421],{"class":191,"line":237},[189,419,420],{"class":195}," 161927",[189,422,423],{"class":199}," tree\n",[12,425,426],{},"If you want to see the contents of a file in the repository, Git has to download it:",[180,428,430],{"className":371,"code":429,"language":373,"meta":185,"style":185},"$ git cat-file -p HEAD:README.md\nremote: Enumerating objects: 1, done.\nremote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 1 (from 1)\nReceiving objects: 100% (1/1), 1.64 KiB | 1.64 MiB/s, done.\n\n[![Build status](https://github.com/git/git/workflows/CI/badge.svg)](https://github.com/git/git/actions?query=branch%3Amaster+event%3Apush)\n\nGit - fast, scalable, distributed revision control system\n=========================================================\n\nGit is a fast, scalable, distributed revision control system with an\nunusually rich command set that provides both high-level operations\nand full access to internals.\n\n[snip]\n",[78,431,432,446,459,489,509,515,565,569,595,601,606,636,666,684,689],{"__ignoreMap":185},[189,433,434,436,438,440,443],{"class":191,"line":192},[189,435,196],{"class":195},[189,437,200],{"class":199},[189,439,384],{"class":199},[189,441,442],{"class":206}," -p",[189,444,445],{"class":199}," HEAD:README.md\n",[189,447,448,450,452,454,457],{"class":191,"line":219},[189,449,240],{"class":195},[189,451,243],{"class":199},[189,453,246],{"class":199},[189,455,456],{"class":199}," 1,",[189,458,252],{"class":199},[189,460,461,463,465,467,469,472,475,477,480,483,485,487],{"class":191,"line":237},[189,462,240],{"class":195},[189,464,292],{"class":199},[189,466,319],{"class":206},[189,468,298],{"class":268},[189,470,471],{"class":206},"0",[189,473,474],{"class":268},"), reused 0 (",[189,476,307],{"class":195},[189,478,479],{"class":206}," 0",[189,481,482],{"class":268},"), pack-reused 1 (",[189,484,316],{"class":195},[189,486,319],{"class":206},[189,488,322],{"class":268},[189,490,491,493,495,497,500,502,505,507],{"class":191,"line":255},[189,492,328],{"class":195},[189,494,246],{"class":199},[189,496,265],{"class":199},[189,498,499],{"class":268}," (1/1), 1.64 KiB ",[189,501,339],{"class":338},[189,503,504],{"class":195}," 1.64",[189,506,345],{"class":199},[189,508,252],{"class":199},[189,510,511],{"class":191,"line":272},[189,512,514],{"emptyLinePlaceholder":513},true,"\n",[189,516,517,520,523,526,529,532,535,538,540,542,544,547,549,552,554,557,560,563],{"class":191,"line":287},[189,518,519],{"class":268},"[",[189,521,522],{"class":338},"!",[189,524,525],{"class":268},"[Build status](https",[189,527,528],{"class":338},"://",[189,530,531],{"class":268},"github.com",[189,533,534],{"class":338},"/",[189,536,537],{"class":268},"git",[189,539,534],{"class":338},[189,541,537],{"class":268},[189,543,534],{"class":338},[189,545,546],{"class":268},"workflows",[189,548,534],{"class":338},[189,550,551],{"class":268},"CI",[189,553,534],{"class":338},[189,555,556],{"class":268},"badge.svg)](",[189,558,559],{"class":195},"https://github.com/git/git/actions?query",[189,561,562],{"class":199},"=branch%3Amaster+event%3Apush",[189,564,322],{"class":268},[189,566,567],{"class":191,"line":325},[189,568,514],{"emptyLinePlaceholder":513},[189,570,571,574,577,580,583,586,589,592],{"class":191,"line":350},[189,572,573],{"class":195},"Git",[189,575,576],{"class":199}," -",[189,578,579],{"class":199}," fast,",[189,581,582],{"class":199}," scalable,",[189,584,585],{"class":199}," distributed",[189,587,588],{"class":199}," revision",[189,590,591],{"class":199}," control",[189,593,594],{"class":199}," system\n",[189,596,598],{"class":191,"line":597},9,[189,599,600],{"class":199},"=========================================================\n",[189,602,604],{"class":191,"line":603},10,[189,605,514],{"emptyLinePlaceholder":513},[189,607,609,611,614,617,619,621,623,625,627,630,633],{"class":191,"line":608},11,[189,610,573],{"class":195},[189,612,613],{"class":199}," is",[189,615,616],{"class":199}," a",[189,618,579],{"class":199},[189,620,582],{"class":199},[189,622,585],{"class":199},[189,624,588],{"class":199},[189,626,591],{"class":199},[189,628,629],{"class":199}," system",[189,631,632],{"class":199}," with",[189,634,635],{"class":199}," an\n",[189,637,639,642,645,648,651,654,657,660,663],{"class":191,"line":638},12,[189,640,641],{"class":195},"unusually",[189,643,644],{"class":199}," rich",[189,646,647],{"class":199}," command",[189,649,650],{"class":199}," set",[189,652,653],{"class":199}," that",[189,655,656],{"class":199}," provides",[189,658,659],{"class":199}," both",[189,661,662],{"class":199}," high-level",[189,664,665],{"class":199}," operations\n",[189,667,669,672,675,678,681],{"class":191,"line":668},13,[189,670,671],{"class":195},"and",[189,673,674],{"class":199}," full",[189,676,677],{"class":199}," access",[189,679,680],{"class":199}," to",[189,682,683],{"class":199}," internals.\n",[189,685,687],{"class":191,"line":686},14,[189,688,514],{"emptyLinePlaceholder":513},[189,690,692],{"class":191,"line":691},15,[189,693,694],{"class":268},"[snip]\n",[12,696,697],{},"As you can see above, Git first talks to the remote repository to download the blob before\nit can display it.",[12,699,700,701,703],{},"When you would like to ",[78,702,134],{}," that file, it needs to download a lot\nmore:",[180,705,707],{"className":371,"code":706,"language":373,"meta":185,"style":185},"$ git blame HEAD README.md\nremote: Enumerating objects: 1, done.\nremote: Counting objects: 100% (1/1), done.\nremote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)\nReceiving objects: 100% (1/1), 1.64 KiB | 1.64 MiB/s, done.\nremote: Enumerating objects: 1, done.\nremote: Counting objects: 100% (1/1), done.\nremote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)\nReceiving objects: 100% (1/1), 1.64 KiB | 1.64 MiB/s, done.\nremote: Enumerating objects: 1, done.\nremote: Counting objects: 100% (1/1), done.\nremote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)\nReceiving objects: 100% (1/1), 1.64 KiB | 1.64 MiB/s, done.\nremote: Enumerating objects: 1, done.\n\n[snip]\n\ndf7375d772 README.md (Ævar Arnfjörð Bjarmason 2021-11-23 17:29:09 +0100  1) [![Build status](https://github.com/git/git/workflows/CI/badge.svg)](https://github.com/git/git/actions?query=branch%3Amaster+event%3Apush)\n5f7864663b README.md (Johannes Schindelin   2019-01-29 06:19:32 -0800  2)\n28513c4f56 README.md (Matthieu Moy          2016-02-25 09:37:29 +0100  3) Git - fast, scalable, distributed revision control system\n28513c4f56 README.md (Matthieu Moy          2016-02-25 09:37:29 +0100  4) =========================================================\n556b6600b2 README   (Nicolas Pitre          2007-01-17 13:04:39 -0500  5)\n556b6600b2 README   (Nicolas Pitre          2007-01-17 13:04:39 -0500  6) Git is a fast, scalable, distributed revision control system with an\n556b6600b2 README   (Nicolas Pitre          2007-01-17 13:04:39 -0500  7) unusually rich command set that provides both high-level operations\n556b6600b2 README   (Nicolas Pitre          2007-01-17 13:04:39 -0500  8) and full access to internals.\n556b6600b2 README   (Nicolas Pitre          2007-01-17 13:04:39 -0500  9)\n\n[snip]\n",[78,708,709,724,736,749,776,794,806,818,844,862,874,886,912,930,942,946,951,956,1023,1051,1079,1102,1131,1154,1177,1200,1222,1227],{"__ignoreMap":185},[189,710,711,713,715,718,721],{"class":191,"line":192},[189,712,196],{"class":195},[189,714,200],{"class":199},[189,716,717],{"class":199}," blame",[189,719,720],{"class":199}," HEAD",[189,722,723],{"class":199}," README.md\n",[189,725,726,728,730,732,734],{"class":191,"line":219},[189,727,240],{"class":195},[189,729,243],{"class":199},[189,731,246],{"class":199},[189,733,456],{"class":199},[189,735,252],{"class":199},[189,737,738,740,742,744,746],{"class":191,"line":237},[189,739,240],{"class":195},[189,741,260],{"class":199},[189,743,246],{"class":199},[189,745,265],{"class":199},[189,747,748],{"class":268}," (1/1), done.\n",[189,750,751,753,755,757,759,761,763,765,767,770,772,774],{"class":191,"line":255},[189,752,240],{"class":195},[189,754,292],{"class":199},[189,756,319],{"class":206},[189,758,298],{"class":268},[189,760,471],{"class":206},[189,762,474],{"class":268},[189,764,307],{"class":195},[189,766,479],{"class":206},[189,768,769],{"class":268},"), pack-reused 0 (",[189,771,316],{"class":195},[189,773,479],{"class":206},[189,775,322],{"class":268},[189,777,778,780,782,784,786,788,790,792],{"class":191,"line":272},[189,779,328],{"class":195},[189,781,246],{"class":199},[189,783,265],{"class":199},[189,785,499],{"class":268},[189,787,339],{"class":338},[189,789,504],{"class":195},[189,791,345],{"class":199},[189,793,252],{"class":199},[189,795,796,798,800,802,804],{"class":191,"line":287},[189,797,240],{"class":195},[189,799,243],{"class":199},[189,801,246],{"class":199},[189,803,456],{"class":199},[189,805,252],{"class":199},[189,807,808,810,812,814,816],{"class":191,"line":325},[189,809,240],{"class":195},[189,811,260],{"class":199},[189,813,246],{"class":199},[189,815,265],{"class":199},[189,817,748],{"class":268},[189,819,820,822,824,826,828,830,832,834,836,838,840,842],{"class":191,"line":350},[189,821,240],{"class":195},[189,823,292],{"class":199},[189,825,319],{"class":206},[189,827,298],{"class":268},[189,829,471],{"class":206},[189,831,474],{"class":268},[189,833,307],{"class":195},[189,835,479],{"class":206},[189,837,769],{"class":268},[189,839,316],{"class":195},[189,841,479],{"class":206},[189,843,322],{"class":268},[189,845,846,848,850,852,854,856,858,860],{"class":191,"line":597},[189,847,328],{"class":195},[189,849,246],{"class":199},[189,851,265],{"class":199},[189,853,499],{"class":268},[189,855,339],{"class":338},[189,857,504],{"class":195},[189,859,345],{"class":199},[189,861,252],{"class":199},[189,863,864,866,868,870,872],{"class":191,"line":603},[189,865,240],{"class":195},[189,867,243],{"class":199},[189,869,246],{"class":199},[189,871,456],{"class":199},[189,873,252],{"class":199},[189,875,876,878,880,882,884],{"class":191,"line":608},[189,877,240],{"class":195},[189,879,260],{"class":199},[189,881,246],{"class":199},[189,883,265],{"class":199},[189,885,748],{"class":268},[189,887,888,890,892,894,896,898,900,902,904,906,908,910],{"class":191,"line":638},[189,889,240],{"class":195},[189,891,292],{"class":199},[189,893,319],{"class":206},[189,895,298],{"class":268},[189,897,471],{"class":206},[189,899,474],{"class":268},[189,901,307],{"class":195},[189,903,479],{"class":206},[189,905,769],{"class":268},[189,907,316],{"class":195},[189,909,479],{"class":206},[189,911,322],{"class":268},[189,913,914,916,918,920,922,924,926,928],{"class":191,"line":668},[189,915,328],{"class":195},[189,917,246],{"class":199},[189,919,265],{"class":199},[189,921,499],{"class":268},[189,923,339],{"class":338},[189,925,504],{"class":195},[189,927,345],{"class":199},[189,929,252],{"class":199},[189,931,932,934,936,938,940],{"class":191,"line":686},[189,933,240],{"class":195},[189,935,243],{"class":199},[189,937,246],{"class":199},[189,939,456],{"class":199},[189,941,252],{"class":199},[189,943,944],{"class":191,"line":691},[189,945,514],{"emptyLinePlaceholder":513},[189,947,949],{"class":191,"line":948},16,[189,950,694],{"class":268},[189,952,954],{"class":191,"line":953},17,[189,955,514],{"emptyLinePlaceholder":513},[189,957,959,962,965,968,971,974,977,980,983,986,989,991,993,995,997,999,1001,1003,1005,1007,1009,1011,1013,1015,1017,1019,1021],{"class":191,"line":958},18,[189,960,961],{"class":195},"df7375d772",[189,963,964],{"class":199}," README.md",[189,966,967],{"class":268}," (Ævar ",[189,969,970],{"class":199},"Arnfjörð",[189,972,973],{"class":199}," Bjarmason",[189,975,976],{"class":199}," 2021-11-23",[189,978,979],{"class":199}," 17:29:09",[189,981,982],{"class":199}," +0100",[189,984,985],{"class":206},"  1",[189,987,988],{"class":268},") [",[189,990,522],{"class":338},[189,992,525],{"class":268},[189,994,528],{"class":338},[189,996,531],{"class":268},[189,998,534],{"class":338},[189,1000,537],{"class":268},[189,1002,534],{"class":338},[189,1004,537],{"class":268},[189,1006,534],{"class":338},[189,1008,546],{"class":268},[189,1010,534],{"class":338},[189,1012,551],{"class":268},[189,1014,534],{"class":338},[189,1016,556],{"class":268},[189,1018,559],{"class":195},[189,1020,562],{"class":199},[189,1022,322],{"class":268},[189,1024,1026,1029,1031,1034,1037,1040,1043,1046,1049],{"class":191,"line":1025},19,[189,1027,1028],{"class":195},"5f7864663b",[189,1030,964],{"class":199},[189,1032,1033],{"class":268}," (Johannes ",[189,1035,1036],{"class":199},"Schindelin",[189,1038,1039],{"class":199},"   2019-01-29",[189,1041,1042],{"class":199}," 06:19:32",[189,1044,1045],{"class":206}," -0800",[189,1047,1048],{"class":206},"  2",[189,1050,322],{"class":268},[189,1052,1054,1057,1059,1062,1065,1068,1071,1073,1076],{"class":191,"line":1053},20,[189,1055,1056],{"class":195},"28513c4f56",[189,1058,964],{"class":199},[189,1060,1061],{"class":268}," (Matthieu ",[189,1063,1064],{"class":199},"Moy",[189,1066,1067],{"class":199},"          2016-02-25",[189,1069,1070],{"class":199}," 09:37:29",[189,1072,982],{"class":199},[189,1074,1075],{"class":206},"  3",[189,1077,1078],{"class":268},") Git - fast, scalable, distributed revision control system\n",[189,1080,1082,1084,1086,1088,1090,1092,1094,1096,1099],{"class":191,"line":1081},21,[189,1083,1056],{"class":195},[189,1085,964],{"class":199},[189,1087,1061],{"class":268},[189,1089,1064],{"class":199},[189,1091,1067],{"class":199},[189,1093,1070],{"class":199},[189,1095,982],{"class":199},[189,1097,1098],{"class":206},"  4",[189,1100,1101],{"class":268},") =========================================================\n",[189,1103,1105,1108,1111,1114,1117,1120,1123,1126,1129],{"class":191,"line":1104},22,[189,1106,1107],{"class":195},"556b6600b2",[189,1109,1110],{"class":199}," README",[189,1112,1113],{"class":268},"   (Nicolas ",[189,1115,1116],{"class":199},"Pitre",[189,1118,1119],{"class":199},"          2007-01-17",[189,1121,1122],{"class":199}," 13:04:39",[189,1124,1125],{"class":206}," -0500",[189,1127,1128],{"class":206},"  5",[189,1130,322],{"class":268},[189,1132,1134,1136,1138,1140,1142,1144,1146,1148,1151],{"class":191,"line":1133},23,[189,1135,1107],{"class":195},[189,1137,1110],{"class":199},[189,1139,1113],{"class":268},[189,1141,1116],{"class":199},[189,1143,1119],{"class":199},[189,1145,1122],{"class":199},[189,1147,1125],{"class":206},[189,1149,1150],{"class":206},"  6",[189,1152,1153],{"class":268},") Git is a fast, scalable, distributed revision control system with an\n",[189,1155,1157,1159,1161,1163,1165,1167,1169,1171,1174],{"class":191,"line":1156},24,[189,1158,1107],{"class":195},[189,1160,1110],{"class":199},[189,1162,1113],{"class":268},[189,1164,1116],{"class":199},[189,1166,1119],{"class":199},[189,1168,1122],{"class":199},[189,1170,1125],{"class":206},[189,1172,1173],{"class":206},"  7",[189,1175,1176],{"class":268},") unusually rich command set that provides both high-level operations\n",[189,1178,1180,1182,1184,1186,1188,1190,1192,1194,1197],{"class":191,"line":1179},25,[189,1181,1107],{"class":195},[189,1183,1110],{"class":199},[189,1185,1113],{"class":268},[189,1187,1116],{"class":199},[189,1189,1119],{"class":199},[189,1191,1122],{"class":199},[189,1193,1125],{"class":206},[189,1195,1196],{"class":206},"  8",[189,1198,1199],{"class":268},") and full access to internals.\n",[189,1201,1203,1205,1207,1209,1211,1213,1215,1217,1220],{"class":191,"line":1202},26,[189,1204,1107],{"class":195},[189,1206,1110],{"class":199},[189,1208,1113],{"class":268},[189,1210,1116],{"class":199},[189,1212,1119],{"class":199},[189,1214,1122],{"class":199},[189,1216,1125],{"class":206},[189,1218,1219],{"class":206},"  9",[189,1221,322],{"class":268},[189,1223,1225],{"class":191,"line":1224},27,[189,1226,514],{"emptyLinePlaceholder":513},[189,1228,1230],{"class":191,"line":1229},28,[189,1231,694],{"class":268},[12,1233,1234,1235,1237],{},"We've truncated the output, but as you can see, Git goes to the server for each\nrevision of that file separately. That's really inefficient. With\n",[78,1236,144],{}," we can ask Git to download all blobs:",[180,1239,1241],{"className":182,"code":1240,"language":184,"meta":185,"style":185},"$ git backfill\nremote: Enumerating objects: 50711, done.\nremote: Counting objects: 100% (15438/15438), done.\nremote: Compressing objects: 100% (708/708), done.\nremote: Total 50711 (delta 15154), reused 14730 (delta 14730), pack-reused 35273 (from 1)\nReceiving objects: 100% (50711/50711), 11.62 MiB | 12.28 MiB/s, done.\nResolving deltas: 100% (49154/49154), done.\nremote: Enumerating objects: 50017, done.\nremote: Counting objects: 100% (10826/10826), done.\nremote: Compressing objects: 100% (634/634), done.\nremote: Total 50017 (delta 10580), reused 10192 (delta 10192), pack-reused 39191 (from 1)\nReceiving objects: 100% (50017/50017), 12.17 MiB | 12.33 MiB/s, done.\nResolving deltas: 100% (48301/48301), done.\nremote: Enumerating objects: 47303, done.\nremote: Counting objects: 100% (7311/7311), done.\nremote: Compressing objects: 100% (618/618), done.\nremote: Total 47303 (delta 7021), reused 6693 (delta 6693), pack-reused 39992 (from 1)\nReceiving objects: 100% (47303/47303), 40.84 MiB | 15.26 MiB/s, done.\nResolving deltas: 100% (43788/43788), done.\n",[78,1242,1243,1252,1265,1278,1291,1322,1342,1353,1366,1379,1392,1423,1443,1454,1467,1480,1493,1524,1544],{"__ignoreMap":185},[189,1244,1245,1247,1249],{"class":191,"line":192},[189,1246,196],{"class":195},[189,1248,200],{"class":199},[189,1250,1251],{"class":199}," backfill\n",[189,1253,1254,1256,1258,1260,1263],{"class":191,"line":219},[189,1255,240],{"class":195},[189,1257,243],{"class":199},[189,1259,246],{"class":199},[189,1261,1262],{"class":199}," 50711,",[189,1264,252],{"class":199},[189,1266,1267,1269,1271,1273,1275],{"class":191,"line":237},[189,1268,240],{"class":195},[189,1270,260],{"class":199},[189,1272,246],{"class":199},[189,1274,265],{"class":199},[189,1276,1277],{"class":268}," (15438/15438), done.\n",[189,1279,1280,1282,1284,1286,1288],{"class":191,"line":255},[189,1281,240],{"class":195},[189,1283,277],{"class":199},[189,1285,246],{"class":199},[189,1287,265],{"class":199},[189,1289,1290],{"class":268}," (708/708), done.\n",[189,1292,1293,1295,1297,1300,1302,1305,1308,1310,1313,1316,1318,1320],{"class":191,"line":272},[189,1294,240],{"class":195},[189,1296,292],{"class":199},[189,1298,1299],{"class":206}," 50711",[189,1301,298],{"class":268},[189,1303,1304],{"class":206},"15154",[189,1306,1307],{"class":268},"), reused 14730 (",[189,1309,307],{"class":195},[189,1311,1312],{"class":206}," 14730",[189,1314,1315],{"class":268},"), pack-reused 35273 (",[189,1317,316],{"class":195},[189,1319,319],{"class":206},[189,1321,322],{"class":268},[189,1323,1324,1326,1328,1330,1333,1335,1338,1340],{"class":191,"line":287},[189,1325,328],{"class":195},[189,1327,246],{"class":199},[189,1329,265],{"class":199},[189,1331,1332],{"class":268}," (50711/50711), 11.62 MiB ",[189,1334,339],{"class":338},[189,1336,1337],{"class":195}," 12.28",[189,1339,345],{"class":199},[189,1341,252],{"class":199},[189,1343,1344,1346,1348,1350],{"class":191,"line":325},[189,1345,353],{"class":195},[189,1347,356],{"class":199},[189,1349,265],{"class":199},[189,1351,1352],{"class":268}," (49154/49154), done.\n",[189,1354,1355,1357,1359,1361,1364],{"class":191,"line":350},[189,1356,240],{"class":195},[189,1358,243],{"class":199},[189,1360,246],{"class":199},[189,1362,1363],{"class":199}," 50017,",[189,1365,252],{"class":199},[189,1367,1368,1370,1372,1374,1376],{"class":191,"line":597},[189,1369,240],{"class":195},[189,1371,260],{"class":199},[189,1373,246],{"class":199},[189,1375,265],{"class":199},[189,1377,1378],{"class":268}," (10826/10826), done.\n",[189,1380,1381,1383,1385,1387,1389],{"class":191,"line":603},[189,1382,240],{"class":195},[189,1384,277],{"class":199},[189,1386,246],{"class":199},[189,1388,265],{"class":199},[189,1390,1391],{"class":268}," (634/634), done.\n",[189,1393,1394,1396,1398,1401,1403,1406,1409,1411,1414,1417,1419,1421],{"class":191,"line":608},[189,1395,240],{"class":195},[189,1397,292],{"class":199},[189,1399,1400],{"class":206}," 50017",[189,1402,298],{"class":268},[189,1404,1405],{"class":206},"10580",[189,1407,1408],{"class":268},"), reused 10192 (",[189,1410,307],{"class":195},[189,1412,1413],{"class":206}," 10192",[189,1415,1416],{"class":268},"), pack-reused 39191 (",[189,1418,316],{"class":195},[189,1420,319],{"class":206},[189,1422,322],{"class":268},[189,1424,1425,1427,1429,1431,1434,1436,1439,1441],{"class":191,"line":638},[189,1426,328],{"class":195},[189,1428,246],{"class":199},[189,1430,265],{"class":199},[189,1432,1433],{"class":268}," (50017/50017), 12.17 MiB ",[189,1435,339],{"class":338},[189,1437,1438],{"class":195}," 12.33",[189,1440,345],{"class":199},[189,1442,252],{"class":199},[189,1444,1445,1447,1449,1451],{"class":191,"line":668},[189,1446,353],{"class":195},[189,1448,356],{"class":199},[189,1450,265],{"class":199},[189,1452,1453],{"class":268}," (48301/48301), done.\n",[189,1455,1456,1458,1460,1462,1465],{"class":191,"line":686},[189,1457,240],{"class":195},[189,1459,243],{"class":199},[189,1461,246],{"class":199},[189,1463,1464],{"class":199}," 47303,",[189,1466,252],{"class":199},[189,1468,1469,1471,1473,1475,1477],{"class":191,"line":691},[189,1470,240],{"class":195},[189,1472,260],{"class":199},[189,1474,246],{"class":199},[189,1476,265],{"class":199},[189,1478,1479],{"class":268}," (7311/7311), done.\n",[189,1481,1482,1484,1486,1488,1490],{"class":191,"line":948},[189,1483,240],{"class":195},[189,1485,277],{"class":199},[189,1487,246],{"class":199},[189,1489,265],{"class":199},[189,1491,1492],{"class":268}," (618/618), done.\n",[189,1494,1495,1497,1499,1502,1504,1507,1510,1512,1515,1518,1520,1522],{"class":191,"line":953},[189,1496,240],{"class":195},[189,1498,292],{"class":199},[189,1500,1501],{"class":206}," 47303",[189,1503,298],{"class":268},[189,1505,1506],{"class":206},"7021",[189,1508,1509],{"class":268},"), reused 6693 (",[189,1511,307],{"class":195},[189,1513,1514],{"class":206}," 6693",[189,1516,1517],{"class":268},"), pack-reused 39992 (",[189,1519,316],{"class":195},[189,1521,319],{"class":206},[189,1523,322],{"class":268},[189,1525,1526,1528,1530,1532,1535,1537,1540,1542],{"class":191,"line":958},[189,1527,328],{"class":195},[189,1529,246],{"class":199},[189,1531,265],{"class":199},[189,1533,1534],{"class":268}," (47303/47303), 40.84 MiB ",[189,1536,339],{"class":338},[189,1538,1539],{"class":195}," 15.26",[189,1541,345],{"class":199},[189,1543,252],{"class":199},[189,1545,1546,1548,1550,1552],{"class":191,"line":1025},[189,1547,353],{"class":195},[189,1549,356],{"class":199},[189,1551,265],{"class":199},[189,1553,1554],{"class":268}," (43788/43788), done.\n",[12,1556,1557],{},"This backfills all blobs, turning the blobless clone into a full clone:",[180,1559,1561],{"className":182,"code":1560,"language":184,"meta":185,"style":185},"$ git cat-file --batch-all-objects --batch-check='%(objecttype)' | sort | uniq -c\n 148031 blob\n  83977 commit\n 161927 tree\n",[78,1562,1563,1587,1595,1601],{"__ignoreMap":185},[189,1564,1565,1567,1569,1571,1573,1575,1577,1579,1581,1583,1585],{"class":191,"line":192},[189,1566,196],{"class":195},[189,1568,200],{"class":199},[189,1570,384],{"class":199},[189,1572,387],{"class":206},[189,1574,390],{"class":206},[189,1576,393],{"class":199},[189,1578,396],{"class":338},[189,1580,399],{"class":195},[189,1582,396],{"class":338},[189,1584,404],{"class":195},[189,1586,407],{"class":206},[189,1588,1589,1592],{"class":191,"line":219},[189,1590,1591],{"class":195}," 148031",[189,1593,1594],{"class":199}," blob\n",[189,1596,1597,1599],{"class":191,"line":237},[189,1598,412],{"class":195},[189,1600,415],{"class":199},[189,1602,1603,1605],{"class":191,"line":255},[189,1604,420],{"class":195},[189,1606,423],{"class":199},[12,1608,1609,1610,1615,1616,1621,1622,116],{},"This ",[16,1611,1614],{"href":1612,"rel":1613},"https://lore.kernel.org/git/pull.1820.v3.git.1738602667.gitgitgadget@gmail.com/",[],"project","\nwas led by ",[16,1617,1620],{"href":1618,"rel":1619},"https://stolee.dev/",[],"Derrick Stolee"," and was merged with\n",[16,1623,1626],{"href":1624,"rel":1625},"https://gitlab.com/gitlab-org/git/-/commit/e565f3755342caf1d21e22359eaf09ec11d8c0ae",[],"e565f37553",[82,1628,40],{"id":1629},"introduction-of-zlib-ng",[12,1631,1632,1633,1636,1637,1644,1645,1647,1648,1653,1654,1656],{},"All objects in the ",[78,1634,1635],{},".git/"," folder are compressed by Git using ",[16,1638,1641],{"href":1639,"rel":1640},"https://zlib.net/",[],[78,1642,1643],{},"zlib",". ",[78,1646,1643],{}," is the reference implementation for the ",[16,1649,1652],{"href":1650,"rel":1651},"https://datatracker.ietf.org/doc/html/rfc1950",[],"RFC\n1950",": ZLIB Compressed Data\nFormat. Created in 1995, ",[78,1655,1643],{}," has a long history and is incredibly\nportable, even supporting many systems that predate the Internet. Because of its\nwide support of architectures and compilers, it has limitations in what it is\ncapable of.",[12,1658,1659,1660,1667,1668,1670],{},"The fork ",[16,1661,1664],{"href":1662,"rel":1663},"https://github.com/zlib-ng/zlib-ng",[],[78,1665,1666],{},"zlib-ng"," was created to\naccommodate the limitations. ",[78,1669,1666],{}," aims to be optimized for modern\nsystems. This fork drops support for legacy systems and instead brings in\npatches for Intel optimizations, some Cloudflare optimizations, and a couple\nother smaller patches.",[12,1672,1673,1674,1676,1677,1679,1680,1682,1683,1685],{},"The ",[78,1675,1666],{}," library itself provides a compatibility layer for ",[78,1678,1643],{},". The\ncompatibility later allows ",[78,1681,1666],{}," to be a drop-in replacement for ",[78,1684,1643],{},", but\nthat layer is not available on all Linux distributions. In Git 2.49:",[26,1687,1688,1691],{},[29,1689,1690],{},"A compatibility layer was added to the Git project.",[29,1692,1693,1694,1701,1702,116],{},"Build options were added to both to the ",[16,1695,1698],{"href":1696,"rel":1697},"https://gitlab.com/gitlab-org/git/-/blob/b9d6f64393275b505937a8621a6cc4875adde8e0/Makefile#L186-187",[],[78,1699,1700],{},"Makefile","\nand ",[16,1703,1706],{"href":1704,"rel":1705},"https://gitlab.com/gitlab-org/git/-/blob/b9d6f64393275b505937a8621a6cc4875adde8e0/meson.build#L795-811",[],"Meson Build file",[12,1708,1709,1710,116],{},"These additions make it easier to benefit from the performance improvements of\n",[78,1711,1666],{},[12,1713,1714,1715,1717,1718,1720],{},"In local benchmarks, we've seen a ~25% speedup when using ",[78,1716,1666],{}," instead of ",[78,1719,1643],{},". And we're in the process of rolling out these changes to\nGitLab.com, too.",[12,1722,1723,1724,1726,1727,1729,1730,178],{},"If you want to benefit from the gains of ",[78,1725,1666],{},", first verify if Git\non your machine is already using ",[78,1728,1666],{}," by running\n",[78,1731,1732],{},"git version --build-options",[180,1734,1736],{"className":182,"code":1735,"language":184,"meta":185,"style":185},"$ git version --build-options\ngit version 2.47.1\ncpu: x86_64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nlibcurl: 8.6.0\nOpenSSL: OpenSSL 3.2.2 4 Jun 2024\nzlib: 1.3.1.zlib-ng\n",[78,1737,1738,1750,1759,1767,1786,1794,1801,1809,1817,1837],{"__ignoreMap":185},[189,1739,1740,1742,1744,1747],{"class":191,"line":192},[189,1741,196],{"class":195},[189,1743,200],{"class":199},[189,1745,1746],{"class":199}," version",[189,1748,1749],{"class":206}," --build-options\n",[189,1751,1752,1754,1756],{"class":191,"line":219},[189,1753,537],{"class":195},[189,1755,1746],{"class":199},[189,1757,1758],{"class":206}," 2.47.1\n",[189,1760,1761,1764],{"class":191,"line":237},[189,1762,1763],{"class":195},"cpu:",[189,1765,1766],{"class":199}," x86_64\n",[189,1768,1769,1772,1775,1778,1780,1783],{"class":191,"line":255},[189,1770,1771],{"class":195},"no",[189,1773,1774],{"class":199}," commit",[189,1776,1777],{"class":199}," associated",[189,1779,632],{"class":199},[189,1781,1782],{"class":199}," this",[189,1784,1785],{"class":199}," build\n",[189,1787,1788,1791],{"class":191,"line":272},[189,1789,1790],{"class":195},"sizeof-long:",[189,1792,1793],{"class":206}," 8\n",[189,1795,1796,1799],{"class":191,"line":287},[189,1797,1798],{"class":195},"sizeof-size_t:",[189,1800,1793],{"class":206},[189,1802,1803,1806],{"class":191,"line":325},[189,1804,1805],{"class":195},"shell-path:",[189,1807,1808],{"class":199}," /bin/sh\n",[189,1810,1811,1814],{"class":191,"line":350},[189,1812,1813],{"class":195},"libcurl:",[189,1815,1816],{"class":206}," 8.6.0\n",[189,1818,1819,1822,1825,1828,1831,1834],{"class":191,"line":597},[189,1820,1821],{"class":195},"OpenSSL:",[189,1823,1824],{"class":199}," OpenSSL",[189,1826,1827],{"class":206}," 3.2.2",[189,1829,1830],{"class":206}," 4",[189,1832,1833],{"class":199}," Jun",[189,1835,1836],{"class":206}," 2024\n",[189,1838,1839,1842],{"class":191,"line":603},[189,1840,1841],{"class":195},"zlib:",[189,1843,1844],{"class":199}," 1.3.1.zlib-ng\n",[12,1846,1847,1848,1850,1851,1853],{},"If the last line includes ",[78,1849,1666],{}," then your Git is already built\nusing the faster ",[78,1852,1643],{}," variant. If not, you can either:",[26,1855,1856,1862],{},[29,1857,1858,1859,1861],{},"Ask the maintainer of the Git package you are using to include ",[78,1860,1666],{}," support.",[29,1863,1864],{},"Build Git yourself from source.",[12,1866,1867,1868,1873,1874,1879,1880,116],{},"These ",[16,1869,1872],{"href":1870,"rel":1871},"https://gitlab.com/gitlab-org/git/-/commit/9d0e81e2ae3bd7f6d8a655be53c2396d7af3d2b0",[],"changes","\nwere ",[16,1875,1878],{"href":1876,"rel":1877},"https://lore.kernel.org/git/20250128-b4-pks-compat-drop-uncompress2-v4-0-129bc36ae8f5@pks.im/",[],"introduced","\nby ",[16,1881,1884],{"href":1882,"rel":1883},"https://gitlab.com/pks-gitlab",[],"Patrick Steinhardt",[82,1886,46],{"id":1887},"continued-iteration-on-meson",[12,1889,1890,1891,1644,1896,1901,1902,1907,1908,1913,1914,116],{},"In our article about the Git 2.48 release,\nwe touched on ",[16,1892,1895],{"href":1893,"rel":1894},"https://about.gitlab.com/blog/whats-new-in-git-2-48-0/#meson-build-system",[],"the introduction of the Meson build system",[16,1897,1900],{"href":1898,"rel":1899},"https://en.wikipedia.org/wiki/Meson_(software)",[],"Meson"," is\na build automation tool used by the Git project that at some point might replace ",[16,1903,1906],{"href":1904,"rel":1905},"https://en.wikipedia.org/wiki/Autoconf",[],"Autoconf",",\n",[16,1909,1912],{"href":1910,"rel":1911},"https://en.wikipedia.org/wiki/CMake",[],"CMake",", and maybe even\n",[16,1915,1918],{"href":1916,"rel":1917},"https://en.wikipedia.org/wiki/Make_(software)",[],"Make",[12,1920,1921],{},"During this release cycle, work continued on using Meson, adding various missing\nfeatures and stabilization fixes:",[26,1923,1924,1937,1953,1965,1980],{},[29,1925,1926,1931,1932,116],{},[16,1927,1930],{"href":1928,"rel":1929},"https://lore.kernel.org/git/20250122-b4-pks-meson-additions-v3-0-5a51eb5d3dcd@pks.im/",[],"Improved test coverage for\nCI","\nwas merged in\n",[16,1933,1936],{"href":1934,"rel":1935},"https://gitlab.com/gitlab-org/git/-/commit/72f1ddfbc95b47c6011bb423e6947418d1d72709",[],"72f1ddfbc9",[29,1938,1939,1947,1948,116],{},[16,1940,1943,1944],{"href":1941,"rel":1942},"https://lore.kernel.org/git/20250219-b4-pks-meson-contrib-v2-0-1ba5d7fde0b9@pks.im/",[],"Bits and pieces to use Meson in ",[78,1945,1946],{},"contrib/","\nwere merged in\n",[16,1949,1952],{"href":1950,"rel":1951},"https://gitlab.com/gitlab-org/git/-/commit/2a1530a953cc4d2ae62416db86c545c7ccb73ace",[],"2a1530a953",[29,1954,1955,1947,1960,116],{},[16,1956,1959],{"href":1957,"rel":1958},"https://lore.kernel.org/git/20250226-b4-pks-meson-improvements-v3-0-60c77cf673ae@pks.im/",[],"Assorted fixes and improvements to the build procedure based on\nmeson",[16,1961,1964],{"href":1962,"rel":1963},"https://gitlab.com/gitlab-org/git/-/commit/ab09eddf601501290b5c719574fbe6c02314631f",[],"ab09eddf60",[29,1966,1967,1931,1975,116],{},[16,1968,1971,1972],{"href":1969,"rel":1970},"https://lore.kernel.org/git/20250117-b4-pks-build-subtree-v1-0-03c2ed6cc42e@pks.im/",[],"Making Meson aware of building\n",[78,1973,1974],{},"git-subtree(1)",[16,1976,1979],{"href":1977,"rel":1978},"https://gitlab.com/gitlab-org/git/-/commit/3ddeb7f3373ae0e309d9df62ada24375afa456c7",[],"3ddeb7f337",[29,1981,1982,1931,1987,116],{},[16,1983,1986],{"href":1984,"rel":1985},"https://lore.kernel.org/git/20241227-b4-pks-meson-docs-v2-0-f61e63edbfa1@pks.im/",[],"Learn Meson to generate HTML documentation\npages",[16,1988,1991],{"href":1989,"rel":1990},"https://gitlab.com/gitlab-org/git/-/commit/1b4e9a5f8b5f048972c21fe8acafe0404096f694",[],"1b4e9a5f8b",[12,1993,1994,1995,116],{},"All these efforts were carried out by ",[16,1996,1884],{"href":1882,"rel":1997},[],[82,1999,52],{"id":2000},"deprecation-of-gitbranches-and-gitremotes",[12,2002,2003,2004,2007,2008,2011,2012,2015,2016,2019,2020,2022,2023,2025],{},"You are probably aware of the existence of the ",[78,2005,2006],{},".git"," directory, and what is\ninside. But have you ever heard about the sub-directories ",[78,2009,2010],{},".git/branches/"," and\n",[78,2013,2014],{},".git/remotes/","? As you might know, reference to branches are stored in\n",[78,2017,2018],{},".git/refs/heads/",", so that's not what ",[78,2021,2010],{}," is for, and what about\n",[78,2024,2014],{},"?",[12,2027,2028,2029,2035,2036,2042,2043,1907,2048,2055,2056,2061,2062,2064,2065,2067,2068,2073],{},"Way back in 2005, ",[16,2030,2033],{"href":2031,"rel":2032},"https://git-scm.com/docs/git-fetch#_named_file_in_git_dirbranches",[],[78,2034,2010],{},"\nwas introduced to store a shorthand name for a remote, and a few months later they were\nmoved to ",[16,2037,2040],{"href":2038,"rel":2039},"https://git-scm.com/docs/git-fetch#_named_file_in_git_dirremotes",[],[78,2041,2014],{},".\nIn ",[16,2044,2047],{"href":2045,"rel":2046},"https://lore.kernel.org/git/Pine.LNX.4.63.0604301520460.2646@wbgn013.biozentrum.uni-wuerzburg.de/",[],"2006",[16,2049,2052],{"href":2050,"rel":2051},"https://git-scm.com/docs/git-config",[],[78,2053,2054],{},"git-config(1)"," learned to store\n",[16,2057,2060],{"href":2058,"rel":2059},"https://git-scm.com/docs/git-config#Documentation/git-config.txt-remoteltnamegturl",[],"remotes",".\nThis has become the standard way to configure remotes and, in 2011, the\ndirectories ",[78,2063,2010],{}," and ",[78,2066,2014],{}," were\n",[16,2069,2072],{"href":2070,"rel":2071},"https://gitlab.com/git-scm/git/-/commit/3d3d282146e13f2d7f055ad056956fd8e5d7ed29#e615263aaf131d42be8b0d0888ebd3fec954c6c9_132_124",[],"documented","\nas being \"legacy\" and no longer used in modern repositories.",[12,2075,2076,2077,2082,2083,2088,2089,2064,2091,2093],{},"In 2024, the document ",[16,2078,2081],{"href":2079,"rel":2080},"https://git-scm.com/docs/BreakingChanges",[],"BreakingChanges","\nwas started to outline breaking changes for the next major version of Git\n(v3.0). While this release is not planned to happen any time soon, this document\nkeeps track of changes that are expected to be part of that release.\nIn ",[16,2084,2087],{"href":2085,"rel":2086},"https://gitlab.com/git-scm/git/-/commit/8ccc75c2452b5814d2445d60d54266293ca48674",[],"8ccc75c245",",\nthe use of the directories ",[78,2090,2010],{},[78,2092,2014],{}," was added to\nthis document and that officially marks as them deprecated and to be removed in\nGit 3.0.",[12,2095,2096,2097,2100,2101,116],{},"Thanks to ",[16,2098,1884],{"href":1882,"rel":2099},[]," for\n",[16,2102,2105],{"href":2103,"rel":2104},"https://lore.kernel.org/git/20250122-pks-remote-branches-deprecation-v4-5-5cbf5b28afd5@pks.im/",[],"formalizing this deprecation",[82,2107,58],{"id":2108},"rust-bindings-for-libgit",[12,2110,2111,2112,2115],{},"When compiling Git, an internal library ",[78,2113,2114],{},"libgit.a"," is made. This library\ncontains some of the core functionality of Git.",[12,2117,2118,2119,2064,2122,2125,2126,2132],{},"While this library (and most of Git) is written in C, in Git 2.49 bindings were\nadded to make some of these functions available in Rust. To achieve this, two\nnew Cargo packages were created: ",[78,2120,2121],{},"libgit-sys",[78,2123,2124],{},"libgit-rs",". These packages\nlive in the ",[16,2127,2130],{"href":2128,"rel":2129},"https://gitlab.com/gitlab-org/git/-/tree/master/contrib",[],[78,2131,1946],{}," subdirectory in the Git source tree.",[12,2134,2135,2136,2141,2142,2147,2148,2150,2151,2153,2154,2156,2157,2159],{},"It's pretty\n",[16,2137,2140],{"href":2138,"rel":2139},"https://doc.rust-lang.org/cargo/reference/build-scripts.html#-sys-packages",[],"common","\nto split out a library into two packages when a ",[16,2143,2146],{"href":2144,"rel":2145},"https://en.wikipedia.org/wiki/Foreign_function_interface",[],"Foreign Function\nInterface"," is used.\nThe ",[78,2149,2121],{}," package provides the pure interface to C functions and links to\nthe native ",[78,2152,2114],{}," library. The package ",[78,2155,2124],{}," provides a high-level\ninterface to the functions in ",[78,2158,2121],{}," with a feel that is more idiomatic to\nRust.",[12,2161,2162,2163,116],{},"So far, the functionality in these Rust packages is very limited. It only\nprovides an interface to interact with the ",[78,2164,2054],{},[12,2166,2167,2168,2173,2174,116],{},"This initiative was led by ",[16,2169,2172],{"href":2170,"rel":2171},"https://lore.kernel.org/git/8793ff64a7f6c4c04dd03b71162a85849feda944.1738187176.git.steadmon@google.com/",[],"Josh Steadmon"," and was merged with ",[16,2175,2178],{"href":2176,"rel":2177},"https://gitlab.com/gitlab-org/git/-/commit/a4af0b6288e25eb327ae9018cee09def9e43f1cd",[],"a4af0b6288",[82,2180,64],{"id":2181},"new-name-hashing-algorithm",[12,2183,2184,2185,2187],{},"The Git object database in ",[78,2186,1635],{}," stores most of its data in packfiles. And\npackfiles are also used to submit objects between Git server and client over the\nwire.",[12,2189,2190,2191,2198,2199,2201,2202,2205],{},"You can read all about the format at\n",[16,2192,2195],{"href":2193,"rel":2194},"https://git-scm.com/docs/gitformat-pack",[],[78,2196,2197],{},"gitformat-pack(5)",". One important\naspect of the packfiles is delta-compression. With delta-compression not every\nobject is stored as-is, but some objects are saved as a ",[105,2200,307],{}," of another\n",[105,2203,2204],{},"base",". So instead of saving the full contents of the objects, changes compared\nto another object are stored.",[12,2207,2208,2209,116],{},"Without going into the details how these deltas are calculated or stored, you\ncan imagine that it is important group files together that are very similar. In\nv2.48 and earlier, Git looked at the last 16 characters of the path name to\ndetermine whether blobs might be similar. This algorithm is named version ",[78,2210,154],{},[12,2212,2213,2214,2216,2217,2219,2220,2223,2224,116],{},"In Git 2.49, version ",[78,2215,158],{}," is available. This is an iteration on version ",[78,2218,154],{},", but\nmodified so the effect of the parent directory is reduced. You can specify the\nname-hash algorithm version you want to use with option ",[78,2221,2222],{},"--name-hash-version"," of\n",[16,2225,2228],{"href":2226,"rel":2227},"https://git-scm.com/docs/git-repack",[],[78,2229,2230],{},"git-repack(1)",[12,2232,2233,2236,2237,178],{},[16,2234,1620],{"href":1618,"rel":2235},[],", who drove this project, did some\ncomparison in resulting packfile size after running ",[78,2238,2239],{},"git repack -adf --name-hash-version=\u003Cn>",[2241,2242,2243,2259],"table",{},[2244,2245,2246],"thead",{},[2247,2248,2249,2253,2256],"tr",{},[2250,2251,2252],"th",{},"Repo",[2250,2254,2255],{},"Version 1 size",[2250,2257,2258],{},"Version 2 size",[2260,2261,2262,2278,2289,2300],"tbody",{},[2247,2263,2264,2272,2275],{},[2265,2266,2267],"td",{},[16,2268,2271],{"href":2269,"rel":2270},"https://github.com/microsoft/fluentui",[],"fluentui",[2265,2273,2274],{},"440 MB",[2265,2276,2277],{},"161 MB",[2247,2279,2280,2283,2286],{},[2265,2281,2282],{},"Repo B",[2265,2284,2285],{},"6,248 MB",[2265,2287,2288],{},"856 MB",[2247,2290,2291,2294,2297],{},[2265,2292,2293],{},"Repo C",[2265,2295,2296],{},"37,278 MB",[2265,2298,2299],{},"6,921 MB",[2247,2301,2302,2305,2308],{},[2265,2303,2304],{},"Repo D",[2265,2306,2307],{},"131,204 MB",[2265,2309,2310],{},"7,463 MB",[12,2312,2313,2314,2319,2320,116],{},"You can read more of the details in the ",[16,2315,2318],{"href":2316,"rel":2317},"https://lore.kernel.org/git/pull.1823.v4.git.1738004554.gitgitgadget@gmail.com/",[],"patch\nset",",\nwhich is merged in\n",[16,2321,2324],{"href":2322,"rel":2323},"https://gitlab.com/gitlab-org/git/-/commit/aae91a86fb2a71ff89a71b63ccec3a947b26ca51",[],"aae91a86fb",[82,2326,70],{"id":2327},"promisor-remote-capability",[12,2329,2330,2331,2336],{},"It's known that Git isn't great in dealing with large files. There are some\nsolutions to this problem, like ",[16,2332,2335],{"href":2333,"rel":2334},"https://git-lfs.com/",[],"Git LFS",", but there are\nstill some shortcomings. To give a few:",[26,2338,2339,2342,2345,2348],{},[29,2340,2341],{},"With Git LFS the user has to configure which files to put in LFS. The server has\nno control about that and has to serve all files.",[29,2343,2344],{},"Whenever a file is committed to the repository, there is no way to get it out\nagain without rewriting history. This is annoying, especially for large files,\nbecause they are stuck for eternity.",[29,2346,2347],{},"Users cannot change their mind on which files to put into Git LFS.",[29,2349,2350],{},"A tool like Git LFS requires significant effort to set up, learn, and use\ncorrectly.",[12,2352,2353],{},"For some time, Git has had the concept of promisor remotes. This feature can be used to deal with large files, and in Git 2.49 this feature took a step forward.",[12,2355,2356,2357,2360,2361,2363],{},"The idea for the new “promisor-remote” capability is relatively simple: Instead of sending all\nobjects itself, a Git server can tell to the Git client \"Hey, go download these\nobjects from ",[105,2358,2359],{},"XYZ","\". ",[105,2362,2359],{}," would be a promisor remote.",[12,2365,2366,2367,2374],{},"Git 2.49 enables the server to advertise the information of the promisor remote\nto the client. This change is an extension to\n",[16,2368,2371],{"href":2369,"rel":2370},"https://git-scm.com/docs/gitprotocol-v2",[],[78,2372,2373],{},"gitprotocol-v2",". While the server\nand the client are transmitting data to each other, the server can send  names and URLs of the promisor remotes it knows\nabout.",[12,2376,2377],{},"So far, the client is not using the promisor remote info it gets from the server during clone, so all\nobjects are still transmitted from the remote the clone initiated from. We are planning to continue work on this feature, making it use promisor remote info from the server, and making it easier to use.",[12,2379,1609,2380,2384,2385,2390,2391,116],{},[16,2381,2318],{"href":2382,"rel":2383},"https://lore.kernel.org/git/20250218113204.2847463-1-christian.couder@gmail.com/",[],"\nwas submitted by ",[16,2386,2389],{"href":2387,"rel":2388},"https://gitlab.com/chriscool",[],"Christian Couder"," and merged\nwith\n",[16,2392,2395],{"href":2393,"rel":2394},"https://gitlab.com/gitlab-org/git/-/commit/2c6fd30198187c928cbf927802556908c381799c",[],"2c6fd30198",[82,2397,76,2399],{"id":2398},"thin-clone-using-revision",[78,2400,80],{},[12,2402,2403,2404,2406,2407,2412,2413,2416,2417,2420,2421,2424,2425,2428,2429,2431,2432,2435],{},"A new ",[78,2405,80],{}," option was added to\n",[16,2408,2410],{"href":90,"rel":2409},[],[78,2411,94],{},". This enables you to create\na thin clone of a repository that only contains the history of the given\nrevision. The option is similar to ",[78,2414,2415],{},"--branch",", but accepts a ref name (like\n",[78,2418,2419],{},"refs/heads/main",", ",[78,2422,2423],{},"refs/tags/v1.0",", and ",[78,2426,2427],{},"refs/merge-requests/123",") or a\nhexadecimal commit object ID. The difference to ",[78,2430,2415],{}," is that it does not\ncreate a tracking branch and detaches ",[78,2433,2434],{},"HEAD",". This means it's not suited if you\nwant to contribute back to that branch.",[12,2437,2438,2439,2441,2442,2445],{},"You can use ",[78,2440,80],{}," in combination with ",[78,2443,2444],{},"--depth"," to create a very minimal\nclone. A suggested use-case is for automated testing. When you have a CI system\nthat needs to check out a branch (or any reference) to perform autonomous\ntesting on the source code, having a minimal clone is all you need.",[12,2447,2448,2449,2454,2455,1879,2460,116],{},"This\n",[16,2450,2453],{"href":2451,"rel":2452},"https://gitlab.com/gitlab-org/git/-/commit/5785d9143bcb3ef19452a83bc2e870ff3d5ed95a",[],"change","\nwas\n",[16,2456,2459],{"href":2457,"rel":2458},"https://lore.kernel.org/git/20250206-toon-clone-refs-v7-0-4622b7392202@iotcl.com/",[],"driven",[16,2461,7],{"href":2462,"rel":2463},"https://gitlab.com/toon",[],[2465,2466,2468],"h1",{"id":2467},"read-more","Read more",[26,2470,2471,2478,2485],{},[29,2472,2473],{},[16,2474,2477],{"href":2475,"rel":2476},"https://about.gitlab.com/blog/whats-new-in-git-2-48-0/",[],"What’s new in Git 2.48.0?",[29,2479,2480],{},[16,2481,2484],{"href":2482,"rel":2483},"https://about.gitlab.com/blog/whats-new-in-git-2-47-0/",[],"What’s new in Git 2.47.0?",[29,2486,2487],{},[16,2488,2491],{"href":2489,"rel":2490},"https://about.gitlab.com/blog/whats-new-in-git-2-46-0/",[],"What’s new in Git 2.46.0?",[2493,2494,2495],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":185,"searchDepth":219,"depth":219,"links":2497},[2498,2499,2500,2501,2502,2503,2504,2505],{"id":84,"depth":219,"text":34},{"id":1629,"depth":219,"text":40},{"id":1887,"depth":219,"text":46},{"id":2000,"depth":219,"text":52},{"id":2108,"depth":219,"text":58},{"id":2181,"depth":219,"text":64},{"id":2327,"depth":219,"text":70},{"id":2398,"depth":219,"text":2506},"Thin clone using --revision","open-source","2025-03-14","Learn about the latest version of Git, including improved performance thanks to zlib-ng, a new name-hashing algorithm, and git-backfill(1).","md",null,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663087/Blog/Hero%20Images/git3-cover.png",{},"/en-us/blog/whats-new-in-git-2-49-0",{"title":5,"description":2509,"ogTitle":5,"ogDescription":2509,"noIndex":2516,"ogImage":2512,"ogUrl":2517,"ogSiteName":2518,"ogType":2519,"canonicalUrls":2517},false,"https://about.gitlab.com/blog/whats-new-in-git-2-49-0","https://about.gitlab.com","article","whats-new-in-git-2-49-0","en-us/blog/whats-new-in-git-2-49-0",[2523,2524,537],"community","open source","BlogPost","IviGxBfviq0t_szsjfD8UkoSPtjhxFiIm8fSCfDCB_8",{"logo":2528,"freeTrial":2532,"sales":2537,"login":2542,"items":2547,"search":2873,"minimal":2904,"duo":2923,"switchNav":2932,"pricingDeployment":2943},{"config":2529},{"href":534,"dataGaName":2530,"dataGaLocation":2531},"gitlab logo","header",{"text":2533,"config":2534},"Get free trial",{"href":2535,"dataGaName":2536,"dataGaLocation":2531},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":2538,"config":2539},"Request a demo",{"href":2540,"dataGaName":2541,"dataGaLocation":2531},"/sales/?contact-topic=request-demo","sales",{"text":2543,"config":2544},"Sign in",{"href":2545,"dataGaName":2546,"dataGaLocation":2531},"https://gitlab.com/users/sign_in/","sign in",[2548,2577,2677,2682,2795,2851],{"text":2549,"config":2550,"menu":2552},"Platform",{"dataNavLevelOne":2551},"platform",{"type":2553,"columns":2554},"cards",[2555,2561,2569],{"title":2549,"description":2556,"link":2557},"The intelligent orchestration platform for DevSecOps",{"text":2558,"config":2559},"Explore our Platform",{"href":2560,"dataGaName":2551,"dataGaLocation":2531},"/platform/",{"title":2562,"description":2563,"link":2564},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":2565,"config":2566},"Meet GitLab Duo",{"href":2567,"dataGaName":2568,"dataGaLocation":2531},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":2570,"description":2571,"link":2572},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":2573,"config":2574},"Learn more",{"href":2575,"dataGaName":2576,"dataGaLocation":2531},"/why-gitlab/","why gitlab",{"text":2578,"left":513,"config":2579,"menu":2581},"Product",{"dataNavLevelOne":2580},"solutions",{"type":2582,"link":2583,"columns":2587,"feature":2656},"lists",{"text":2584,"config":2585},"View all Solutions",{"href":2586,"dataGaName":2580,"dataGaLocation":2531},"/solutions/",[2588,2612,2635],{"title":2589,"description":2590,"link":2591,"items":2596},"Automation","CI/CD and automation to accelerate deployment",{"config":2592},{"icon":2593,"href":2594,"dataGaName":2595,"dataGaLocation":2531},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[2597,2601,2604,2608],{"text":2598,"config":2599},"CI/CD",{"href":2600,"dataGaLocation":2531,"dataGaName":2598},"/solutions/continuous-integration/",{"text":2562,"config":2602},{"href":2567,"dataGaLocation":2531,"dataGaName":2603},"gitlab duo agent platform - product menu",{"text":2605,"config":2606},"Source Code Management",{"href":2607,"dataGaLocation":2531,"dataGaName":2605},"/solutions/source-code-management/",{"text":2609,"config":2610},"Automated Software Delivery",{"href":2594,"dataGaLocation":2531,"dataGaName":2611},"Automated software delivery",{"title":2613,"description":2614,"link":2615,"items":2620},"Security","Deliver code faster without compromising security",{"config":2616},{"href":2617,"dataGaName":2618,"dataGaLocation":2531,"icon":2619},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[2621,2625,2630],{"text":2622,"config":2623},"Application Security Testing",{"href":2617,"dataGaName":2624,"dataGaLocation":2531},"Application security testing",{"text":2626,"config":2627},"Software Supply Chain Security",{"href":2628,"dataGaLocation":2531,"dataGaName":2629},"/solutions/supply-chain/","Software supply chain security",{"text":2631,"config":2632},"Software Compliance",{"href":2633,"dataGaName":2634,"dataGaLocation":2531},"/solutions/software-compliance/","software compliance",{"title":2636,"link":2637,"items":2642},"Measurement",{"config":2638},{"icon":2639,"href":2640,"dataGaName":2641,"dataGaLocation":2531},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[2643,2647,2651],{"text":2644,"config":2645},"Visibility & Measurement",{"href":2640,"dataGaLocation":2531,"dataGaName":2646},"Visibility and Measurement",{"text":2648,"config":2649},"Value Stream Management",{"href":2650,"dataGaLocation":2531,"dataGaName":2648},"/solutions/value-stream-management/",{"text":2652,"config":2653},"Analytics & Insights",{"href":2654,"dataGaLocation":2531,"dataGaName":2655},"/solutions/analytics-and-insights/","Analytics and insights",{"title":2657,"type":2582,"items":2658},"GitLab for",[2659,2665,2671],{"text":2660,"config":2661},"Enterprise",{"icon":2662,"href":2663,"dataGaLocation":2531,"dataGaName":2664},"Building","/enterprise/","enterprise",{"text":2666,"config":2667},"Small Business",{"icon":2668,"href":2669,"dataGaLocation":2531,"dataGaName":2670},"Work","/small-business/","small business",{"text":2672,"config":2673},"Public Sector",{"icon":2674,"href":2675,"dataGaLocation":2531,"dataGaName":2676},"Organization","/solutions/public-sector/","public sector",{"text":2678,"config":2679},"Pricing",{"href":2680,"dataGaName":2681,"dataGaLocation":2531,"dataNavLevelOne":2681},"/pricing/","pricing",{"text":2683,"config":2684,"menu":2686},"Resources",{"dataNavLevelOne":2685},"resources",{"type":2582,"link":2687,"columns":2691,"feature":2784},{"text":2688,"config":2689},"View all resources",{"href":2690,"dataGaName":2685,"dataGaLocation":2531},"/resources/",[2692,2725,2752],{"title":2693,"items":2694},"Getting started",[2695,2700,2705,2710,2715,2720],{"text":2696,"config":2697},"Install",{"href":2698,"dataGaName":2699,"dataGaLocation":2531},"/install/","install",{"text":2701,"config":2702},"Quick start guides",{"href":2703,"dataGaName":2704,"dataGaLocation":2531},"/get-started/","quick setup checklists",{"text":2706,"config":2707},"Learn",{"href":2708,"dataGaLocation":2531,"dataGaName":2709},"https://university.gitlab.com/","learn",{"text":2711,"config":2712},"Product documentation",{"href":2713,"dataGaName":2714,"dataGaLocation":2531},"https://docs.gitlab.com/","product documentation",{"text":2716,"config":2717},"Best practice videos",{"href":2718,"dataGaName":2719,"dataGaLocation":2531},"/getting-started-videos/","best practice videos",{"text":2721,"config":2722},"Integrations",{"href":2723,"dataGaName":2724,"dataGaLocation":2531},"/integrations/","integrations",{"title":2726,"items":2727},"Discover",[2728,2733,2738,2743,2747],{"text":2729,"config":2730},"Customer success stories",{"href":2731,"dataGaName":2732,"dataGaLocation":2531},"/customers/","customer success stories",{"text":2734,"config":2735},"Blog",{"href":2736,"dataGaName":2737,"dataGaLocation":2531},"/blog/","blog",{"text":2739,"config":2740},"Demo Hub",{"href":2741,"dataGaName":2742,"dataGaLocation":2531},"/demo-hub/","demo hub",{"text":2744,"config":2745},"The Source",{"href":2746,"dataGaName":2737,"dataGaLocation":2531},"/the-source/",{"text":2748,"config":2749},"Remote",{"href":2750,"dataGaName":2751,"dataGaLocation":2531},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":2753,"items":2754},"Connect",[2755,2760,2765,2769,2774,2779],{"text":2756,"config":2757},"GitLab Services",{"href":2758,"dataGaName":2759,"dataGaLocation":2531},"/services/","services",{"text":2761,"config":2762},"Contribute",{"href":2763,"dataGaName":2764,"dataGaLocation":2531},"https://contributors.gitlab.com","contribute",{"text":2766,"config":2767},"Community",{"href":2768,"dataGaName":2523,"dataGaLocation":2531},"/community/",{"text":2770,"config":2771},"Forum",{"href":2772,"dataGaName":2773,"dataGaLocation":2531},"https://forum.gitlab.com/","forum",{"text":2775,"config":2776},"Events",{"href":2777,"dataGaName":2778,"dataGaLocation":2531},"/events/","events",{"text":2780,"config":2781},"Partners",{"href":2782,"dataGaName":2783,"dataGaLocation":2531},"/partners/","partners",{"config":2785,"title":2788,"text":2789,"link":2790},{"background":2786,"textColor":2787},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":2791,"config":2792},"Read the latest",{"href":2793,"dataGaName":2794,"dataGaLocation":2531},"/whats-new/","whats new",{"text":2796,"config":2797,"menu":2799},"Company",{"dataNavLevelOne":2798},"company",{"type":2582,"columns":2800},[2801],{"items":2802},[2803,2808,2814,2816,2821,2826,2831,2836,2841,2846],{"text":2804,"config":2805},"About",{"href":2806,"dataGaName":2807,"dataGaLocation":2531},"/company/","about",{"text":2809,"config":2810,"footerGa":2813},"Jobs",{"href":2811,"dataGaName":2812,"dataGaLocation":2531},"/jobs/","jobs",{"dataGaName":2812},{"text":2775,"config":2815},{"href":2777,"dataGaName":2778,"dataGaLocation":2531},{"text":2817,"config":2818},"Leadership",{"href":2819,"dataGaName":2820,"dataGaLocation":2531},"/company/team/e-group/","leadership",{"text":2822,"config":2823},"Handbook",{"href":2824,"dataGaName":2825,"dataGaLocation":2531},"https://handbook.gitlab.com/","handbook",{"text":2827,"config":2828},"Investor relations",{"href":2829,"dataGaName":2830,"dataGaLocation":2531},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":2832,"config":2833},"Trust Center",{"href":2834,"dataGaName":2835,"dataGaLocation":2531},"/security/","trust center",{"text":2837,"config":2838},"AI Transparency Center",{"href":2839,"dataGaName":2840,"dataGaLocation":2531},"/ai-transparency-center/","ai transparency center",{"text":2842,"config":2843},"Newsletter",{"href":2844,"dataGaName":2845,"dataGaLocation":2531},"/company/contact/#contact-forms","newsletter",{"text":2847,"config":2848},"Press",{"href":2849,"dataGaName":2850,"dataGaLocation":2531},"/press/","press",{"text":2852,"config":2853,"menu":2854},"Contact us",{"dataNavLevelOne":2798},{"type":2582,"columns":2855},[2856],{"items":2857},[2858,2863,2868],{"text":2859,"config":2860},"Talk to sales",{"href":2861,"dataGaName":2862,"dataGaLocation":2531},"/sales/","talk to sales",{"text":2864,"config":2865},"Support portal",{"href":2866,"dataGaName":2867,"dataGaLocation":2531},"https://support.gitlab.com/hc/en-us","support portal",{"text":2869,"config":2870},"Customer portal",{"href":2871,"dataGaName":2872,"dataGaLocation":2531},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":2874,"login":2875,"suggestions":2882},"Close",{"text":2876,"link":2877},"To search repositories and projects, login to",{"text":2878,"config":2879},"gitlab.com",{"href":2545,"dataGaName":2880,"dataGaLocation":2881},"search login","search",{"text":2883,"default":2884},"Suggestions",[2885,2887,2891,2893,2897,2901],{"text":2562,"config":2886},{"href":2567,"dataGaName":2562,"dataGaLocation":2881},{"text":2888,"config":2889},"Code Suggestions (AI)",{"href":2890,"dataGaName":2888,"dataGaLocation":2881},"/solutions/code-suggestions/",{"text":2598,"config":2892},{"href":2600,"dataGaName":2598,"dataGaLocation":2881},{"text":2894,"config":2895},"GitLab on AWS",{"href":2896,"dataGaName":2894,"dataGaLocation":2881},"/partners/technology-partners/aws/",{"text":2898,"config":2899},"GitLab on Google Cloud",{"href":2900,"dataGaName":2898,"dataGaLocation":2881},"/partners/technology-partners/google-cloud-platform/",{"text":2902,"config":2903},"Why GitLab?",{"href":2575,"dataGaName":2902,"dataGaLocation":2881},{"freeTrial":2905,"mobileIcon":2910,"desktopIcon":2915,"secondaryButton":2918},{"text":2906,"config":2907},"Start free trial",{"href":2908,"dataGaName":2536,"dataGaLocation":2909},"https://gitlab.com/-/trials/new/","nav",{"altText":2911,"config":2912},"Gitlab Icon",{"src":2913,"dataGaName":2914,"dataGaLocation":2909},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":2911,"config":2916},{"src":2917,"dataGaName":2914,"dataGaLocation":2909},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":2919,"config":2920},"Get Started",{"href":2921,"dataGaName":2922,"dataGaLocation":2909},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":2924,"mobileIcon":2928,"desktopIcon":2930},{"text":2925,"config":2926},"Learn more about GitLab Duo",{"href":2567,"dataGaName":2927,"dataGaLocation":2909},"gitlab duo",{"altText":2911,"config":2929},{"src":2913,"dataGaName":2914,"dataGaLocation":2909},{"altText":2911,"config":2931},{"src":2917,"dataGaName":2914,"dataGaLocation":2909},{"button":2933,"mobileIcon":2938,"desktopIcon":2940},{"text":2934,"config":2935},"/switch",{"href":2936,"dataGaName":2937,"dataGaLocation":2909},"#contact","switch",{"altText":2911,"config":2939},{"src":2913,"dataGaName":2914,"dataGaLocation":2909},{"altText":2911,"config":2941},{"src":2942,"dataGaName":2914,"dataGaLocation":2909},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":2944,"mobileIcon":2949,"desktopIcon":2951},{"text":2945,"config":2946},"Back to pricing",{"href":2680,"dataGaName":2947,"dataGaLocation":2909,"icon":2948},"back to pricing","GoBack",{"altText":2911,"config":2950},{"src":2913,"dataGaName":2914,"dataGaLocation":2909},{"altText":2911,"config":2952},{"src":2917,"dataGaName":2914,"dataGaLocation":2909},{"title":2954,"titleMobile":2955,"button":2956,"config":2961},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":2573,"config":2957},{"href":2958,"dataGaName":2959,"dataGaLocation":2960},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":2962,"disabled":2516},"release",{"data":2964},{"text":2965,"source":2966,"edit":2972,"contribute":2977,"config":2982,"items":2987,"minimal":3197},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":2967,"config":2968},"View page source",{"href":2969,"dataGaName":2970,"dataGaLocation":2971},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":2973,"config":2974},"Edit this page",{"href":2975,"dataGaName":2976,"dataGaLocation":2971},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":2978,"config":2979},"Please contribute",{"href":2980,"dataGaName":2981,"dataGaLocation":2971},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":2983,"facebook":2984,"youtube":2985,"linkedin":2986},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[2988,3035,3089,3133,3165],{"title":2678,"links":2989,"subMenu":3004},[2990,2994,2999],{"text":2991,"config":2992},"View plans",{"href":2680,"dataGaName":2993,"dataGaLocation":2971},"view plans",{"text":2995,"config":2996},"Why Premium?",{"href":2997,"dataGaName":2998,"dataGaLocation":2971},"/pricing/premium/","why premium",{"text":3000,"config":3001},"Why Ultimate?",{"href":3002,"dataGaName":3003,"dataGaLocation":2971},"/pricing/ultimate/","why ultimate",[3005],{"title":3006,"links":3007},"Contact Us",[3008,3011,3013,3015,3020,3025,3030],{"text":3009,"config":3010},"Contact sales",{"href":2861,"dataGaName":2541,"dataGaLocation":2971},{"text":2864,"config":3012},{"href":2866,"dataGaName":2867,"dataGaLocation":2971},{"text":2869,"config":3014},{"href":2871,"dataGaName":2872,"dataGaLocation":2971},{"text":3016,"config":3017},"Status",{"href":3018,"dataGaName":3019,"dataGaLocation":2971},"https://status.gitlab.com/","status",{"text":3021,"config":3022},"Terms of use",{"href":3023,"dataGaName":3024,"dataGaLocation":2971},"/terms/","terms of use",{"text":3026,"config":3027},"Privacy statement",{"href":3028,"dataGaName":3029,"dataGaLocation":2971},"/privacy/","privacy statement",{"text":3031,"config":3032},"Cookie preferences",{"dataGaName":3033,"dataGaLocation":2971,"id":3034,"isOneTrustButton":513},"cookie preferences","ot-sdk-btn",{"title":2578,"links":3036,"subMenu":3045},[3037,3041],{"text":3038,"config":3039},"DevSecOps platform",{"href":2560,"dataGaName":3040,"dataGaLocation":2971},"devsecops platform",{"text":3042,"config":3043},"AI-Assisted Development",{"href":2567,"dataGaName":3044,"dataGaLocation":2971},"ai-assisted development",[3046],{"title":3047,"links":3048},"Topics",[3049,3054,3059,3064,3069,3074,3079,3084],{"text":3050,"config":3051},"CICD",{"href":3052,"dataGaName":3053,"dataGaLocation":2971},"/topics/ci-cd/","cicd",{"text":3055,"config":3056},"GitOps",{"href":3057,"dataGaName":3058,"dataGaLocation":2971},"/topics/gitops/","gitops",{"text":3060,"config":3061},"DevOps",{"href":3062,"dataGaName":3063,"dataGaLocation":2971},"/topics/devops/","devops",{"text":3065,"config":3066},"Version Control",{"href":3067,"dataGaName":3068,"dataGaLocation":2971},"/topics/version-control/","version control",{"text":3070,"config":3071},"DevSecOps",{"href":3072,"dataGaName":3073,"dataGaLocation":2971},"/topics/devsecops/","devsecops",{"text":3075,"config":3076},"Cloud Native",{"href":3077,"dataGaName":3078,"dataGaLocation":2971},"/topics/cloud-native/","cloud native",{"text":3080,"config":3081},"AI for Coding",{"href":3082,"dataGaName":3083,"dataGaLocation":2971},"/topics/devops/ai-for-coding/","ai for coding",{"text":3085,"config":3086},"Agentic AI",{"href":3087,"dataGaName":3088,"dataGaLocation":2971},"/topics/agentic-ai/","agentic ai",{"title":3090,"links":3091},"Solutions",[3092,3094,3096,3101,3105,3108,3112,3115,3117,3120,3123,3128],{"text":2622,"config":3093},{"href":2617,"dataGaName":2622,"dataGaLocation":2971},{"text":2611,"config":3095},{"href":2594,"dataGaName":2595,"dataGaLocation":2971},{"text":3097,"config":3098},"Agile development",{"href":3099,"dataGaName":3100,"dataGaLocation":2971},"/solutions/agile-delivery/","agile delivery",{"text":3102,"config":3103},"SCM",{"href":2607,"dataGaName":3104,"dataGaLocation":2971},"source code management",{"text":3050,"config":3106},{"href":2600,"dataGaName":3107,"dataGaLocation":2971},"continuous integration & delivery",{"text":3109,"config":3110},"Value stream management",{"href":2650,"dataGaName":3111,"dataGaLocation":2971},"value stream management",{"text":3055,"config":3113},{"href":3114,"dataGaName":3058,"dataGaLocation":2971},"/solutions/gitops/",{"text":2660,"config":3116},{"href":2663,"dataGaName":2664,"dataGaLocation":2971},{"text":3118,"config":3119},"Small business",{"href":2669,"dataGaName":2670,"dataGaLocation":2971},{"text":3121,"config":3122},"Public sector",{"href":2675,"dataGaName":2676,"dataGaLocation":2971},{"text":3124,"config":3125},"Education",{"href":3126,"dataGaName":3127,"dataGaLocation":2971},"/solutions/education/","education",{"text":3129,"config":3130},"Financial services",{"href":3131,"dataGaName":3132,"dataGaLocation":2971},"/solutions/finance/","financial services",{"title":2683,"links":3134},[3135,3137,3139,3141,3144,3146,3149,3151,3153,3155,3157,3159,3161,3163],{"text":2696,"config":3136},{"href":2698,"dataGaName":2699,"dataGaLocation":2971},{"text":2701,"config":3138},{"href":2703,"dataGaName":2704,"dataGaLocation":2971},{"text":2706,"config":3140},{"href":2708,"dataGaName":2709,"dataGaLocation":2971},{"text":2711,"config":3142},{"href":2713,"dataGaName":3143,"dataGaLocation":2971},"docs",{"text":2734,"config":3145},{"href":2736,"dataGaName":2737,"dataGaLocation":2971},{"text":3147,"config":3148},"What's new",{"href":2793,"dataGaName":2794,"dataGaLocation":2971},{"text":2729,"config":3150},{"href":2731,"dataGaName":2732,"dataGaLocation":2971},{"text":2748,"config":3152},{"href":2750,"dataGaName":2751,"dataGaLocation":2971},{"text":2756,"config":3154},{"href":2758,"dataGaName":2759,"dataGaLocation":2971},{"text":2761,"config":3156},{"href":2763,"dataGaName":2764,"dataGaLocation":2971},{"text":2766,"config":3158},{"href":2768,"dataGaName":2523,"dataGaLocation":2971},{"text":2770,"config":3160},{"href":2772,"dataGaName":2773,"dataGaLocation":2971},{"text":2775,"config":3162},{"href":2777,"dataGaName":2778,"dataGaLocation":2971},{"text":2780,"config":3164},{"href":2782,"dataGaName":2783,"dataGaLocation":2971},{"title":2796,"links":3166},[3167,3169,3171,3173,3175,3177,3181,3186,3188,3190,3192],{"text":2804,"config":3168},{"href":2806,"dataGaName":2798,"dataGaLocation":2971},{"text":2809,"config":3170},{"href":2811,"dataGaName":2812,"dataGaLocation":2971},{"text":2817,"config":3172},{"href":2819,"dataGaName":2820,"dataGaLocation":2971},{"text":2822,"config":3174},{"href":2824,"dataGaName":2825,"dataGaLocation":2971},{"text":2827,"config":3176},{"href":2829,"dataGaName":2830,"dataGaLocation":2971},{"text":3178,"config":3179},"Sustainability",{"href":3180,"dataGaName":3178,"dataGaLocation":2971},"/sustainability/",{"text":3182,"config":3183},"Diversity, inclusion and belonging (DIB)",{"href":3184,"dataGaName":3185,"dataGaLocation":2971},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":2832,"config":3187},{"href":2834,"dataGaName":2835,"dataGaLocation":2971},{"text":2842,"config":3189},{"href":2844,"dataGaName":2845,"dataGaLocation":2971},{"text":2847,"config":3191},{"href":2849,"dataGaName":2850,"dataGaLocation":2971},{"text":3193,"config":3194},"Modern Slavery Transparency Statement",{"href":3195,"dataGaName":3196,"dataGaLocation":2971},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":3198},[3199,3202,3205],{"text":3200,"config":3201},"Terms",{"href":3023,"dataGaName":3024,"dataGaLocation":2971},{"text":3203,"config":3204},"Cookies",{"dataGaName":3033,"dataGaLocation":2971,"id":3034,"isOneTrustButton":513},{"text":3206,"config":3207},"Privacy",{"href":3028,"dataGaName":3029,"dataGaLocation":2971},[3209],{"id":3210,"title":7,"body":2511,"config":3211,"content":3213,"description":2511,"extension":3217,"meta":3218,"navigation":513,"path":3219,"seo":3220,"stem":3221,"__hash__":3222},"blogAuthors/en-us/blog/authors/toon-claes.yml",{"template":3212},"BlogAuthor",{"name":7,"config":3214},{"headshot":3215,"ctfId":3216},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663082/Blog/Author%20Headshots/toon_claes_headshot.png","toon","yml",{},"/en-us/blog/authors/toon-claes",{},"en-us/blog/authors/toon-claes","guXJXoqO1anz4H932Namk7kqyZsO1xyVQr6stBL4o18",[3224,3231,3239],{"title":3225,"description":3226,"heroImage":3227,"category":2507,"date":3228,"authors":3229,"slug":3230,"externalUrl":2511},"What's new in Git 2.55.0?","Learn about the new features and changes in Git 2.55, including a new git-history(1) fixup command, an fsmonitor daemon for Linux, pushing to remote groups, and more.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782732487/ztwgrvlolpifo01vj8qc.png","2026-06-29",[7],"whats-new-in-git-2-55-0",{"title":3232,"description":3233,"heroImage":3234,"category":2507,"date":3235,"authors":3236,"slug":3238,"externalUrl":2511},"GitLab AI Hackathon 2026: Meet the winners","Nearly 7,000 developers built 600+ AI agents and flows on GitLab Duo Agent Platform. Find out who won and what they created.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1776457632/llddiylsgwuze0u1rjks.png","2026-04-22",[3237],"Nick Veenhof","gitlab-ai-hackathon-2026-meet-the-winners",{"title":3240,"description":3241,"heroImage":3242,"category":2507,"date":3243,"authors":3244,"slug":3245,"externalUrl":2511},"What’s new in Git 2.54.0?","Learn about release contributions, including new repository maintenance, a new command to edit commit history, a replacement for git-sizer(1), and more.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782734716/ztwgrvlolpifo01vj8qc.png","2026-04-20",[1884],"whats-new-in-git-2-54-0",{"promotions":3247},[3248,3262,3274,3286],{"id":3249,"categories":3250,"header":3252,"text":3253,"button":3254,"image":3259},"ai-modernization",[3251],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":3255,"config":3256},"Get your AI maturity score",{"href":3257,"dataGaName":3258,"dataGaLocation":2737},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":3260},{"src":3261},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":3263,"categories":3264,"header":3266,"text":3253,"button":3267,"image":3271},"devops-modernization",[3265,3073],"product","Are you just managing tools or shipping innovation?",{"text":3268,"config":3269},"Get your DevOps maturity score",{"href":3270,"dataGaName":3258,"dataGaLocation":2737},"/assessments/devops-modernization-assessment/",{"config":3272},{"src":3273},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":3275,"categories":3276,"header":3278,"text":3253,"button":3279,"image":3283},"security-modernization",[3277],"security","Are you trading speed for security?",{"text":3280,"config":3281},"Get your security maturity score",{"href":3282,"dataGaName":3258,"dataGaLocation":2737},"/assessments/security-modernization-assessment/",{"config":3284},{"src":3285},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":3287,"paths":3288,"header":3291,"text":3292,"button":3293,"image":3298},"github-azure-migration",[3289,3290],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":3294,"config":3295},"See how GitLab compares to GitHub",{"href":3296,"dataGaName":3297,"dataGaLocation":2737},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":3299},{"src":3273},{"header":3301,"blurb":3302,"button":3303,"secondaryButton":3308},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":3304,"config":3305},"Get your free trial",{"href":3306,"dataGaName":2536,"dataGaLocation":3307},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":3009,"config":3309},{"href":2861,"dataGaName":2541,"dataGaLocation":3307},1786803754491]