[{"data":1,"prerenderedAt":1495},["ShallowReactive",2],{"/blog/patch-files-for-code-review":3,"navigation-en-us":706,"banner-en-us":1134,"footer-en-us":1144,"blog-post-authors-en-us-David O'Regan":1389,"blog-related-posts-en-us-patch-files-for-code-review":1405,"blog-promotions-en-us":1431,"next-steps-en-us":1485},{"id":4,"title":5,"authors":6,"body":8,"category":686,"date":687,"description":688,"extension":689,"externalUrl":690,"faq":690,"featured":691,"heroImage":692,"meta":693,"navigation":328,"path":694,"seo":695,"slug":699,"stem":700,"tags":701,"template":704,"updatedDate":690,"__hash__":705},"blogPosts/en-us/blog/patch-files-for-code-review.md","How patch files can transform how you review code",[7],"David O'Regan",{"type":9,"value":10,"toc":677},"minimark",[11,26,31,50,54,57,66,251,254,258,261,266,292,296,303,428,435,579,585,599,602,605,613,623,627,630,643,652,655,658,666,673],[12,13,14,15,20,21,25],"p",{},"This post is adapted from a ",[16,17,19],"a",{"href":18},"/blog/better-code-reviews/","GitLab Unfiltered blog post"," written by me, David O'Regan. In ",[16,22,24],{"href":23},"/blog/tips-for-better-code-review/","part one of our series",", we explain the importance of fairness and empathetic thinking in code reviews.",[27,28,30],"h2",{"id":29},"patch-files","Patch files",[12,32,33,34,38,39,43,44,49],{},"Wanna know a ",[35,36,37],"code",{},"git secret","? ",[16,40,30],{"href":41,"rel":42},"https://git-scm.com/docs/git-format-patch",[]," are magic when it comes to code reviews. A ",[16,45,48],{"href":46,"rel":47},"https://www.tutorialspoint.com/git/git_patch_operation.htm",[],"patch is a text file whose contents are similar to Git diff"," but along with code it contains metadata about commits, for example, a patch file will include commit ID, date, commit message, etc. We can create a patch from commits and other people can apply them to their repository.",[27,51,53],{"id":52},"how-to-use-a-patch-file","How to use a patch file",[12,55,56],{},"A patch file is useful for code review because it allows the reviewer to create an actionable piece of code that shares their thoughts with the MR author. The code author can then apply the suggestion directly to their merge request. Patch files foster collaboration because it essentially creates a paired programming session in the review process.",[12,58,59,60,65],{},"This lets other people check your changes in the git patch files for any corrections that need to be made before the changes truly go live. After everything has been checked and corrections made, the changes can be pushed to the main branch of the repository.\nOne of the ",[16,61,64],{"href":62,"rel":63},"https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31686#note_341534370",[],"better examples of a simple patch file in action"," comes from Denys Mishunov, staff frontend engineer on the Create team.",[67,68,73],"pre",{"className":69,"code":70,"language":71,"meta":72,"style":72},"language-bash shiki shiki-themes github-light","Index: app/assets/javascripts/projects/commits/components/author_select.vue\nIDEA additional info:\nSubsystem: com.intellij.openapi.diff.impl.patch.CharsetEP\n\u003C+>UTF-8\n===================================================================\n--- app/assets/javascripts/projects/commits/components/author_select.vue    (revision 697d0734f1ae469a9a3522838e36b435d7cdf0be)\n+++ app/assets/javascripts/projects/commits/components/author_select.vue    (date 1589356024033)\n@@ -110,6 +110,7 @@\n     \u003Cgl-new-dropdown\n       :text=\"dropdownText\"\n       :disabled=\"hasSearchParam\"\n+      toggle-class=\"gl-py-3\"\n       class=\"gl-dropdown w-100 mt-2 mt-sm-0\"\n     >\n       \u003Cgl-new-dropdown-header>\n\n","bash","",[35,74,75,88,100,109,126,132,150,167,182,191,203,214,222,233,239],{"__ignoreMap":72},[76,77,80,84],"span",{"class":78,"line":79},"line",1,[76,81,83],{"class":82},"s7eDp","Index:",[76,85,87],{"class":86},"sYBdl"," app/assets/javascripts/projects/commits/components/author_select.vue\n",[76,89,91,94,97],{"class":78,"line":90},2,[76,92,93],{"class":82},"IDEA",[76,95,96],{"class":86}," additional",[76,98,99],{"class":86}," info:\n",[76,101,103,106],{"class":78,"line":102},3,[76,104,105],{"class":82},"Subsystem:",[76,107,108],{"class":86}," com.intellij.openapi.diff.impl.patch.CharsetEP\n",[76,110,112,116,120,123],{"class":78,"line":111},4,[76,113,115],{"class":114},"sD7c4","\u003C",[76,117,119],{"class":118},"sgsFI","+",[76,121,122],{"class":114},">",[76,124,125],{"class":118},"UTF-8\n",[76,127,129],{"class":78,"line":128},5,[76,130,131],{"class":86},"===================================================================\n",[76,133,135,138,141,144,147],{"class":78,"line":134},6,[76,136,137],{"class":82},"---",[76,139,140],{"class":86}," app/assets/javascripts/projects/commits/components/author_select.vue",[76,142,143],{"class":118},"    (revision ",[76,145,146],{"class":86},"697d0734f1ae469a9a3522838e36b435d7cdf0be",[76,148,149],{"class":118},")\n",[76,151,153,156,158,161,165],{"class":78,"line":152},7,[76,154,155],{"class":82},"+++",[76,157,140],{"class":86},[76,159,160],{"class":118},"    (date ",[76,162,164],{"class":163},"sYu0t","1589356024033",[76,166,149],{"class":118},[76,168,170,173,176,179],{"class":78,"line":169},8,[76,171,172],{"class":82},"@@",[76,174,175],{"class":163}," -110,6",[76,177,178],{"class":86}," +110,7",[76,180,181],{"class":86}," @@\n",[76,183,185,188],{"class":78,"line":184},9,[76,186,187],{"class":114},"     \u003C",[76,189,190],{"class":82},"gl-new-dropdown\n",[76,192,194,197,200],{"class":78,"line":193},10,[76,195,196],{"class":82},"       :text",[76,198,199],{"class":86},"=",[76,201,202],{"class":82},"\"dropdownText\"\n",[76,204,206,209,211],{"class":78,"line":205},11,[76,207,208],{"class":82},"       :disabled",[76,210,199],{"class":86},[76,212,213],{"class":82},"\"hasSearchParam\"\n",[76,215,217,219],{"class":78,"line":216},12,[76,218,119],{"class":82},[76,220,221],{"class":86},"      toggle-class=\"gl-py-3\"\n",[76,223,225,228,230],{"class":78,"line":224},13,[76,226,227],{"class":118},"       class",[76,229,199],{"class":114},[76,231,232],{"class":86},"\"gl-dropdown w-100 mt-2 mt-sm-0\"\n",[76,234,236],{"class":78,"line":235},14,[76,237,238],{"class":114},"     >\n",[76,240,242,245,248],{"class":78,"line":241},15,[76,243,244],{"class":114},"       \u003C",[76,246,247],{"class":82},"gl-new-dropdown-header",[76,249,250],{"class":118},">\n",[12,252,253],{},"To generate this suggestion, Denys pulled down the code he was reviewing and was able to offer a code solution based on his own testing. The patch file contains lots of valuable information, including the file affected, the date the revision was made, and the tool he used to generate the patch.",[27,255,257],{"id":256},"how-to-create-a-patch-file","How to create a patch file",[12,259,260],{},"You can make a patch file using a web editor or with the command line. Read on to see how to create a patch file in GitLab both ways.",[262,263,265],"h3",{"id":264},"patch-files-using-a-web-editor","Patch files using a web editor",[12,267,268,269,274,275,274,280,285,286,291],{},"If you are rocking a nice fancy IDE or text editor, here's some good news: Most support patch files via plugins or out of the box. Here are some links to documentation on how to use patch files with different plugins: ",[16,270,273],{"href":271,"rel":272},"https://github.com/paragdiwan/vscode-git-patch",[],"VSCode",", ",[16,276,279],{"href":277,"rel":278},"https://www.jetbrains.com/help/webstorm/using-patches.html",[],"Webstorm",[16,281,284],{"href":282,"rel":283},"https://atom.io/packages/git-plus",[],"Atom",", and ",[16,287,290],{"href":288,"rel":289},"https://vim.fandom.com/wiki/How_to_make_and_submit_a_patch",[],"Vim",".",[262,293,295],{"id":294},"patch-files-using-the-command-line","Patch files using the command line",[12,297,298,299,302],{},"OK command line users, you’ve made some commits, here’s your ",[35,300,301],{},"git log",":",[67,304,308],{"className":305,"code":306,"language":307,"meta":72,"style":72},"language-shell shiki shiki-themes github-light","git log --pretty=oneline -3\n\n* da33d1k - (feature_branch) Reviewer Commit 1 (7 minutes ago)\n\n* 66a84ah - (feature_branch) Developer 1 Commit (12 minutes ago)\n\n* adsc8cd - (REL-0.5.0, origin/master, origin/HEAD, master) Release 13.0 (2 weeks ago)\n\n```javascript\n","shell",[35,309,310,324,330,355,359,380,384,416,420],{"__ignoreMap":72},[76,311,312,315,318,321],{"class":78,"line":79},[76,313,314],{"class":82},"git",[76,316,317],{"class":86}," log",[76,319,320],{"class":163}," --pretty=oneline",[76,322,323],{"class":163}," -3\n",[76,325,326],{"class":78,"line":90},[76,327,329],{"emptyLinePlaceholder":328},true,"\n",[76,331,332,335,338,341,344,347,350,353],{"class":78,"line":102},[76,333,334],{"class":114},"*",[76,336,337],{"class":118}," da33d1k - (",[76,339,340],{"class":82},"feature_branch",[76,342,343],{"class":118},") Reviewer Commit 1 (",[76,345,346],{"class":82},"7",[76,348,349],{"class":86}," minutes",[76,351,352],{"class":86}," ago",[76,354,149],{"class":118},[76,356,357],{"class":78,"line":111},[76,358,329],{"emptyLinePlaceholder":328},[76,360,361,363,366,368,371,374,376,378],{"class":78,"line":128},[76,362,334],{"class":114},[76,364,365],{"class":118}," 66a84ah - (",[76,367,340],{"class":82},[76,369,370],{"class":118},") Developer 1 Commit (",[76,372,373],{"class":82},"12",[76,375,349],{"class":86},[76,377,352],{"class":86},[76,379,149],{"class":118},[76,381,382],{"class":78,"line":134},[76,383,329],{"emptyLinePlaceholder":328},[76,385,386,388,391,394,397,400,403,406,409,412,414],{"class":78,"line":152},[76,387,334],{"class":114},[76,389,390],{"class":118}," adsc8cd - (",[76,392,393],{"class":82},"REL-0.5.0,",[76,395,396],{"class":86}," origin/master,",[76,398,399],{"class":86}," origin/HEAD,",[76,401,402],{"class":86}," master",[76,404,405],{"class":118},") Release 13.0 (",[76,407,408],{"class":82},"2",[76,410,411],{"class":86}," weeks",[76,413,352],{"class":86},[76,415,149],{"class":118},[76,417,418],{"class":78,"line":169},[76,419,329],{"emptyLinePlaceholder":328},[76,421,422,425],{"class":78,"line":184},[76,423,424],{"class":86},"```",[76,426,427],{"class":82},"javascript\n",[12,429,430,431,434],{},"This command creates a new file, ",[35,432,433],{},"reviewer_commit.patch",", with all changes from the reviewer's latest commit against the feature branch:",[67,436,438],{"className":305,"code":437,"language":307,"meta":72,"style":72},"```text git format-patch HEAD~1 --stdout > reviewer_commit.patch ```\n### How to apply the patch\n\nFirst, take a look at what changes are in the patch. You can do this easily with `git apply`:\n\n```shell git apply --stat reviewer_commit.patch ``` ```text\n\nHeads up: Despite the name, this command won't actually apply the patch. It will just show the statistics about what the patch will do.\n\nSo now that we've had a look, let's test it first because not all patches are created equal:\n\n",[35,439,440,459,465,469,533,537,558,562,570,574],{"__ignoreMap":72},[76,441,442,444,447,450,453,456],{"class":78,"line":79},[76,443,424],{"class":86},[76,445,446],{"class":82},"text",[76,448,449],{"class":86}," git format-patch HEAD~1 ",[76,451,452],{"class":163},"--stdout",[76,454,455],{"class":114}," >",[76,457,458],{"class":86}," reviewer_commit.patch ```\n",[76,460,461],{"class":78,"line":90},[76,462,464],{"class":463},"sAwPA","### How to apply the patch\n",[76,466,467],{"class":78,"line":102},[76,468,329],{"emptyLinePlaceholder":328},[76,470,471,474,477,480,483,486,489,492,495,498,501,504,507,510,513,516,519,522,525,527,530],{"class":78,"line":111},[76,472,473],{"class":82},"First,",[76,475,476],{"class":86}," take",[76,478,479],{"class":86}," a",[76,481,482],{"class":86}," look",[76,484,485],{"class":86}," at",[76,487,488],{"class":86}," what",[76,490,491],{"class":86}," changes",[76,493,494],{"class":86}," are",[76,496,497],{"class":86}," in",[76,499,500],{"class":86}," the",[76,502,503],{"class":86}," patch.",[76,505,506],{"class":86}," You",[76,508,509],{"class":86}," can",[76,511,512],{"class":86}," do",[76,514,515],{"class":86}," this",[76,517,518],{"class":86}," easily",[76,520,521],{"class":86}," with",[76,523,524],{"class":86}," `",[76,526,314],{"class":82},[76,528,529],{"class":86}," apply`",[76,531,532],{"class":163},":\n",[76,534,535],{"class":78,"line":128},[76,536,329],{"emptyLinePlaceholder":328},[76,538,539,541,543,546,549,552,555],{"class":78,"line":134},[76,540,424],{"class":86},[76,542,307],{"class":82},[76,544,545],{"class":86}," git apply ",[76,547,548],{"class":163},"--stat",[76,550,551],{"class":86}," reviewer_commit.patch ```",[76,553,554],{"class":86}," ```",[76,556,557],{"class":82},"text\n",[76,559,560],{"class":78,"line":152},[76,561,329],{"emptyLinePlaceholder":328},[76,563,564,567],{"class":78,"line":169},[76,565,566],{"class":82},"Heads",[76,568,569],{"class":86}," up: Despite the name, this command won't actually apply the patch. It will just show the statistics about what the patch will do.\n",[76,571,572],{"class":78,"line":184},[76,573,329],{"emptyLinePlaceholder":328},[76,575,576],{"class":78,"line":193},[76,577,578],{"class":86},"So now that we've had a look, let's test it first because not all patches are created equal:\n",[12,580,581,584],{},[35,582,583],{},"shell git apply --check reviewer_commit.patch ","\nIf there are no errors we can apply this patch without worrying.",[12,586,587,588,591,592,595,596,598],{},"To apply the patch, you should use ",[35,589,590],{},"git am"," instead of ",[35,593,594],{},"git apply",". The reason: ",[35,597,590],{}," allows you to sign off an applied patch with the reviewer's stamp.",[12,600,601],{},"git am --signoff \u003C reviewer_commit.patch",[12,603,604],{},"Applying: Reviewer Commit 1",[67,606,609],{"className":607,"code":72,"language":608,"meta":72,"style":72},"language-javascript shiki shiki-themes github-light","javascript",[35,610,611],{"__ignoreMap":72},[76,612],{"class":78,"line":79},[12,614,615,616,618,619,622],{},"Now run ",[35,617,301],{}," and you can see the ",[35,620,621],{},"Signed-off-by"," tag in the commit message. This tag makes it very easy to understand how this commit ended up in the codebase.",[262,624,626],{"id":625},"the-benefits-of-patch-files-for-code-reviews","The benefits of patch files for code reviews",[12,628,629],{},"So now that you know how to make a shiny patch file, why would you use patch files as part of a code review process? There are a few reasons you might consider offering a patch file for a change you feel strongly about:",[631,632,633,637,640],"ul",{},[634,635,636],"li",{},"It communicates you have invested a large amount of effort into understanding the author's solution and reasoning",[634,638,639],{},"It demonstrates a passion for using teamwork to arrive at the best solution",[634,641,642],{},"It shows the reviewer is willing to accept responsibility for this merge beyond just reading the code",[12,644,645,646,651],{},"There are a few alternatives to patch files for code reviews. GitLab has a ",[16,647,650],{"href":648,"rel":649},"https://docs.gitlab.com/user/discussions/#suggest-changes",[],"suggestion feature which allows the reviewer to suggest code changes using Markdown in a merge request",". The other option is to write raw code in Markdown right in the comment box. The downside is the reviewer doesn't have the option to test the code they are writing, making both of these options prone to error.",[12,653,654],{},"It is better to use a patch file because it involves the code reviewer in the review process in a collaborative way by default. In order to generate a patch, the reviewer must pull down the code, write the patch, test the change, and then submit it for the code author's consideration. Patch files increase the visibility for the reviewer and offers a fully collaborative experience for the code author.",[12,656,657],{},"Some people might argue patch files are a cheeky way for a reviewer to force a change they would rather see make it into the codebase, but I believe that anyone who has taken the time to check out a branch, run the project, implement a change, and then submits that change back for a discussion is fully embracing collaboration.",[12,659,660,661,291],{},"GitLab is evaluating whether to make patch files ",[16,662,665],{"href":663,"rel":664},"https://gitlab.com/gitlab-org/gitlab/-/issues/220044",[],"part of the code review and merge request workflow",[12,667,668,669,672],{},"Learn more about ",[16,670,671],{"href":23},"the role of fairness in code review in part one of our blog series",". Up next we explain why shipping small merge requests is in line with our iteration value.",[674,675,676],"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 .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}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);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":72,"searchDepth":90,"depth":90,"links":678},[679,680,681],{"id":29,"depth":90,"text":30},{"id":52,"depth":90,"text":53},{"id":256,"depth":90,"text":257,"children":682},[683,684,685],{"id":264,"depth":102,"text":265},{"id":294,"depth":102,"text":295},{"id":625,"depth":102,"text":626},"engineering","2021-03-15","We explain how to use patch files for better code review.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749672273/Blog/Hero%20Images/patch.jpg",{},"/en-us/blog/patch-files-for-code-review",{"title":5,"description":688,"ogTitle":5,"ogDescription":688,"noIndex":691,"ogImage":692,"ogUrl":696,"ogSiteName":697,"ogType":698,"canonicalUrls":696},"https://about.gitlab.com/blog/patch-files-for-code-review","https://about.gitlab.com","article","patch-files-for-code-review","en-us/blog/patch-files-for-code-review",[702,703],"code review","inside GitLab","BlogPost","BohF6ECKdOkf_rSTHoLTgWytsiDBN7XGUvrVBnoTpIA",{"logo":707,"freeTrial":712,"sales":717,"login":722,"items":727,"search":1054,"minimal":1085,"duo":1104,"switchNav":1113,"pricingDeployment":1124},{"config":708},{"href":709,"dataGaName":710,"dataGaLocation":711},"/","gitlab logo","header",{"text":713,"config":714},"Get free trial",{"href":715,"dataGaName":716,"dataGaLocation":711},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":718,"config":719},"Request a demo",{"href":720,"dataGaName":721,"dataGaLocation":711},"/sales/?contact-topic=request-demo","sales",{"text":723,"config":724},"Sign in",{"href":725,"dataGaName":726,"dataGaLocation":711},"https://gitlab.com/users/sign_in/","sign in",[728,757,857,862,976,1032],{"text":729,"config":730,"menu":732},"Platform",{"dataNavLevelOne":731},"platform",{"type":733,"columns":734},"cards",[735,741,749],{"title":729,"description":736,"link":737},"The intelligent orchestration platform for DevSecOps",{"text":738,"config":739},"Explore our Platform",{"href":740,"dataGaName":731,"dataGaLocation":711},"/platform/",{"title":742,"description":743,"link":744},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":745,"config":746},"Meet GitLab Duo",{"href":747,"dataGaName":748,"dataGaLocation":711},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":750,"description":751,"link":752},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":753,"config":754},"Learn more",{"href":755,"dataGaName":756,"dataGaLocation":711},"/why-gitlab/","why gitlab",{"text":758,"left":328,"config":759,"menu":761},"Product",{"dataNavLevelOne":760},"solutions",{"type":762,"link":763,"columns":767,"feature":836},"lists",{"text":764,"config":765},"View all Solutions",{"href":766,"dataGaName":760,"dataGaLocation":711},"/solutions/",[768,792,815],{"title":769,"description":770,"link":771,"items":776},"Automation","CI/CD and automation to accelerate deployment",{"config":772},{"icon":773,"href":774,"dataGaName":775,"dataGaLocation":711},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[777,781,784,788],{"text":778,"config":779},"CI/CD",{"href":780,"dataGaLocation":711,"dataGaName":778},"/solutions/continuous-integration/",{"text":742,"config":782},{"href":747,"dataGaLocation":711,"dataGaName":783},"gitlab duo agent platform - product menu",{"text":785,"config":786},"Source Code Management",{"href":787,"dataGaLocation":711,"dataGaName":785},"/solutions/source-code-management/",{"text":789,"config":790},"Automated Software Delivery",{"href":774,"dataGaLocation":711,"dataGaName":791},"Automated software delivery",{"title":793,"description":794,"link":795,"items":800},"Security","Deliver code faster without compromising security",{"config":796},{"href":797,"dataGaName":798,"dataGaLocation":711,"icon":799},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[801,805,810],{"text":802,"config":803},"Application Security Testing",{"href":797,"dataGaName":804,"dataGaLocation":711},"Application security testing",{"text":806,"config":807},"Software Supply Chain Security",{"href":808,"dataGaLocation":711,"dataGaName":809},"/solutions/supply-chain/","Software supply chain security",{"text":811,"config":812},"Software Compliance",{"href":813,"dataGaName":814,"dataGaLocation":711},"/solutions/software-compliance/","software compliance",{"title":816,"link":817,"items":822},"Measurement",{"config":818},{"icon":819,"href":820,"dataGaName":821,"dataGaLocation":711},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[823,827,831],{"text":824,"config":825},"Visibility & Measurement",{"href":820,"dataGaLocation":711,"dataGaName":826},"Visibility and Measurement",{"text":828,"config":829},"Value Stream Management",{"href":830,"dataGaLocation":711,"dataGaName":828},"/solutions/value-stream-management/",{"text":832,"config":833},"Analytics & Insights",{"href":834,"dataGaLocation":711,"dataGaName":835},"/solutions/analytics-and-insights/","Analytics and insights",{"title":837,"type":762,"items":838},"GitLab for",[839,845,851],{"text":840,"config":841},"Enterprise",{"icon":842,"href":843,"dataGaLocation":711,"dataGaName":844},"Building","/enterprise/","enterprise",{"text":846,"config":847},"Small Business",{"icon":848,"href":849,"dataGaLocation":711,"dataGaName":850},"Work","/small-business/","small business",{"text":852,"config":853},"Public Sector",{"icon":854,"href":855,"dataGaLocation":711,"dataGaName":856},"Organization","/solutions/public-sector/","public sector",{"text":858,"config":859},"Pricing",{"href":860,"dataGaName":861,"dataGaLocation":711,"dataNavLevelOne":861},"/pricing/","pricing",{"text":863,"config":864,"menu":866},"Resources",{"dataNavLevelOne":865},"resources",{"type":762,"link":867,"columns":871,"feature":965},{"text":868,"config":869},"View all resources",{"href":870,"dataGaName":865,"dataGaLocation":711},"/resources/",[872,905,932],{"title":873,"items":874},"Getting started",[875,880,885,890,895,900],{"text":876,"config":877},"Install",{"href":878,"dataGaName":879,"dataGaLocation":711},"/install/","install",{"text":881,"config":882},"Quick start guides",{"href":883,"dataGaName":884,"dataGaLocation":711},"/get-started/","quick setup checklists",{"text":886,"config":887},"Learn",{"href":888,"dataGaLocation":711,"dataGaName":889},"https://university.gitlab.com/","learn",{"text":891,"config":892},"Product documentation",{"href":893,"dataGaName":894,"dataGaLocation":711},"https://docs.gitlab.com/","product documentation",{"text":896,"config":897},"Best practice videos",{"href":898,"dataGaName":899,"dataGaLocation":711},"/getting-started-videos/","best practice videos",{"text":901,"config":902},"Integrations",{"href":903,"dataGaName":904,"dataGaLocation":711},"/integrations/","integrations",{"title":906,"items":907},"Discover",[908,913,918,923,927],{"text":909,"config":910},"Customer success stories",{"href":911,"dataGaName":912,"dataGaLocation":711},"/customers/","customer success stories",{"text":914,"config":915},"Blog",{"href":916,"dataGaName":917,"dataGaLocation":711},"/blog/","blog",{"text":919,"config":920},"Demo Hub",{"href":921,"dataGaName":922,"dataGaLocation":711},"/demo-hub/","demo hub",{"text":924,"config":925},"The Source",{"href":926,"dataGaName":917,"dataGaLocation":711},"/the-source/",{"text":928,"config":929},"Remote",{"href":930,"dataGaName":931,"dataGaLocation":711},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":933,"items":934},"Connect",[935,940,945,950,955,960],{"text":936,"config":937},"GitLab Services",{"href":938,"dataGaName":939,"dataGaLocation":711},"/services/","services",{"text":941,"config":942},"Contribute",{"href":943,"dataGaName":944,"dataGaLocation":711},"https://contributors.gitlab.com","contribute",{"text":946,"config":947},"Community",{"href":948,"dataGaName":949,"dataGaLocation":711},"/community/","community",{"text":951,"config":952},"Forum",{"href":953,"dataGaName":954,"dataGaLocation":711},"https://forum.gitlab.com/","forum",{"text":956,"config":957},"Events",{"href":958,"dataGaName":959,"dataGaLocation":711},"/events/","events",{"text":961,"config":962},"Partners",{"href":963,"dataGaName":964,"dataGaLocation":711},"/partners/","partners",{"config":966,"title":969,"text":970,"link":971},{"background":967,"textColor":968},"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":972,"config":973},"Read the latest",{"href":974,"dataGaName":975,"dataGaLocation":711},"/whats-new/","whats new",{"text":977,"config":978,"menu":980},"Company",{"dataNavLevelOne":979},"company",{"type":762,"columns":981},[982],{"items":983},[984,989,995,997,1002,1007,1012,1017,1022,1027],{"text":985,"config":986},"About",{"href":987,"dataGaName":988,"dataGaLocation":711},"/company/","about",{"text":990,"config":991,"footerGa":994},"Jobs",{"href":992,"dataGaName":993,"dataGaLocation":711},"/jobs/","jobs",{"dataGaName":993},{"text":956,"config":996},{"href":958,"dataGaName":959,"dataGaLocation":711},{"text":998,"config":999},"Leadership",{"href":1000,"dataGaName":1001,"dataGaLocation":711},"/company/team/e-group/","leadership",{"text":1003,"config":1004},"Handbook",{"href":1005,"dataGaName":1006,"dataGaLocation":711},"https://handbook.gitlab.com/","handbook",{"text":1008,"config":1009},"Investor relations",{"href":1010,"dataGaName":1011,"dataGaLocation":711},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":1013,"config":1014},"Trust Center",{"href":1015,"dataGaName":1016,"dataGaLocation":711},"/security/","trust center",{"text":1018,"config":1019},"AI Transparency Center",{"href":1020,"dataGaName":1021,"dataGaLocation":711},"/ai-transparency-center/","ai transparency center",{"text":1023,"config":1024},"Newsletter",{"href":1025,"dataGaName":1026,"dataGaLocation":711},"/company/contact/#contact-forms","newsletter",{"text":1028,"config":1029},"Press",{"href":1030,"dataGaName":1031,"dataGaLocation":711},"/press/","press",{"text":1033,"config":1034,"menu":1035},"Contact us",{"dataNavLevelOne":979},{"type":762,"columns":1036},[1037],{"items":1038},[1039,1044,1049],{"text":1040,"config":1041},"Talk to sales",{"href":1042,"dataGaName":1043,"dataGaLocation":711},"/sales/","talk to sales",{"text":1045,"config":1046},"Support portal",{"href":1047,"dataGaName":1048,"dataGaLocation":711},"https://support.gitlab.com/hc/en-us","support portal",{"text":1050,"config":1051},"Customer portal",{"href":1052,"dataGaName":1053,"dataGaLocation":711},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1055,"login":1056,"suggestions":1063},"Close",{"text":1057,"link":1058},"To search repositories and projects, login to",{"text":1059,"config":1060},"gitlab.com",{"href":725,"dataGaName":1061,"dataGaLocation":1062},"search login","search",{"text":1064,"default":1065},"Suggestions",[1066,1068,1072,1074,1078,1082],{"text":742,"config":1067},{"href":747,"dataGaName":742,"dataGaLocation":1062},{"text":1069,"config":1070},"Code Suggestions (AI)",{"href":1071,"dataGaName":1069,"dataGaLocation":1062},"/solutions/code-suggestions/",{"text":778,"config":1073},{"href":780,"dataGaName":778,"dataGaLocation":1062},{"text":1075,"config":1076},"GitLab on AWS",{"href":1077,"dataGaName":1075,"dataGaLocation":1062},"/partners/technology-partners/aws/",{"text":1079,"config":1080},"GitLab on Google Cloud",{"href":1081,"dataGaName":1079,"dataGaLocation":1062},"/partners/technology-partners/google-cloud-platform/",{"text":1083,"config":1084},"Why GitLab?",{"href":755,"dataGaName":1083,"dataGaLocation":1062},{"freeTrial":1086,"mobileIcon":1091,"desktopIcon":1096,"secondaryButton":1099},{"text":1087,"config":1088},"Start free trial",{"href":1089,"dataGaName":716,"dataGaLocation":1090},"https://gitlab.com/-/trials/new/","nav",{"altText":1092,"config":1093},"Gitlab Icon",{"src":1094,"dataGaName":1095,"dataGaLocation":1090},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1092,"config":1097},{"src":1098,"dataGaName":1095,"dataGaLocation":1090},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1100,"config":1101},"Get Started",{"href":1102,"dataGaName":1103,"dataGaLocation":1090},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":1105,"mobileIcon":1109,"desktopIcon":1111},{"text":1106,"config":1107},"Learn more about GitLab Duo",{"href":747,"dataGaName":1108,"dataGaLocation":1090},"gitlab duo",{"altText":1092,"config":1110},{"src":1094,"dataGaName":1095,"dataGaLocation":1090},{"altText":1092,"config":1112},{"src":1098,"dataGaName":1095,"dataGaLocation":1090},{"button":1114,"mobileIcon":1119,"desktopIcon":1121},{"text":1115,"config":1116},"/switch",{"href":1117,"dataGaName":1118,"dataGaLocation":1090},"#contact","switch",{"altText":1092,"config":1120},{"src":1094,"dataGaName":1095,"dataGaLocation":1090},{"altText":1092,"config":1122},{"src":1123,"dataGaName":1095,"dataGaLocation":1090},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1125,"mobileIcon":1130,"desktopIcon":1132},{"text":1126,"config":1127},"Back to pricing",{"href":860,"dataGaName":1128,"dataGaLocation":1090,"icon":1129},"back to pricing","GoBack",{"altText":1092,"config":1131},{"src":1094,"dataGaName":1095,"dataGaLocation":1090},{"altText":1092,"config":1133},{"src":1098,"dataGaName":1095,"dataGaLocation":1090},{"title":1135,"titleMobile":1136,"button":1137,"config":1142},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":753,"config":1138},{"href":1139,"dataGaName":1140,"dataGaLocation":1141},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":1143,"disabled":691},"release",{"data":1145},{"text":1146,"source":1147,"edit":1153,"contribute":1158,"config":1163,"items":1168,"minimal":1378},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1148,"config":1149},"View page source",{"href":1150,"dataGaName":1151,"dataGaLocation":1152},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1154,"config":1155},"Edit this page",{"href":1156,"dataGaName":1157,"dataGaLocation":1152},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1159,"config":1160},"Please contribute",{"href":1161,"dataGaName":1162,"dataGaLocation":1152},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1164,"facebook":1165,"youtube":1166,"linkedin":1167},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1169,1216,1270,1314,1346],{"title":858,"links":1170,"subMenu":1185},[1171,1175,1180],{"text":1172,"config":1173},"View plans",{"href":860,"dataGaName":1174,"dataGaLocation":1152},"view plans",{"text":1176,"config":1177},"Why Premium?",{"href":1178,"dataGaName":1179,"dataGaLocation":1152},"/pricing/premium/","why premium",{"text":1181,"config":1182},"Why Ultimate?",{"href":1183,"dataGaName":1184,"dataGaLocation":1152},"/pricing/ultimate/","why ultimate",[1186],{"title":1187,"links":1188},"Contact Us",[1189,1192,1194,1196,1201,1206,1211],{"text":1190,"config":1191},"Contact sales",{"href":1042,"dataGaName":721,"dataGaLocation":1152},{"text":1045,"config":1193},{"href":1047,"dataGaName":1048,"dataGaLocation":1152},{"text":1050,"config":1195},{"href":1052,"dataGaName":1053,"dataGaLocation":1152},{"text":1197,"config":1198},"Status",{"href":1199,"dataGaName":1200,"dataGaLocation":1152},"https://status.gitlab.com/","status",{"text":1202,"config":1203},"Terms of use",{"href":1204,"dataGaName":1205,"dataGaLocation":1152},"/terms/","terms of use",{"text":1207,"config":1208},"Privacy statement",{"href":1209,"dataGaName":1210,"dataGaLocation":1152},"/privacy/","privacy statement",{"text":1212,"config":1213},"Cookie preferences",{"dataGaName":1214,"dataGaLocation":1152,"id":1215,"isOneTrustButton":328},"cookie preferences","ot-sdk-btn",{"title":758,"links":1217,"subMenu":1226},[1218,1222],{"text":1219,"config":1220},"DevSecOps platform",{"href":740,"dataGaName":1221,"dataGaLocation":1152},"devsecops platform",{"text":1223,"config":1224},"AI-Assisted Development",{"href":747,"dataGaName":1225,"dataGaLocation":1152},"ai-assisted development",[1227],{"title":1228,"links":1229},"Topics",[1230,1235,1240,1245,1250,1255,1260,1265],{"text":1231,"config":1232},"CICD",{"href":1233,"dataGaName":1234,"dataGaLocation":1152},"/topics/ci-cd/","cicd",{"text":1236,"config":1237},"GitOps",{"href":1238,"dataGaName":1239,"dataGaLocation":1152},"/topics/gitops/","gitops",{"text":1241,"config":1242},"DevOps",{"href":1243,"dataGaName":1244,"dataGaLocation":1152},"/topics/devops/","devops",{"text":1246,"config":1247},"Version Control",{"href":1248,"dataGaName":1249,"dataGaLocation":1152},"/topics/version-control/","version control",{"text":1251,"config":1252},"DevSecOps",{"href":1253,"dataGaName":1254,"dataGaLocation":1152},"/topics/devsecops/","devsecops",{"text":1256,"config":1257},"Cloud Native",{"href":1258,"dataGaName":1259,"dataGaLocation":1152},"/topics/cloud-native/","cloud native",{"text":1261,"config":1262},"AI for Coding",{"href":1263,"dataGaName":1264,"dataGaLocation":1152},"/topics/devops/ai-for-coding/","ai for coding",{"text":1266,"config":1267},"Agentic AI",{"href":1268,"dataGaName":1269,"dataGaLocation":1152},"/topics/agentic-ai/","agentic ai",{"title":1271,"links":1272},"Solutions",[1273,1275,1277,1282,1286,1289,1293,1296,1298,1301,1304,1309],{"text":802,"config":1274},{"href":797,"dataGaName":802,"dataGaLocation":1152},{"text":791,"config":1276},{"href":774,"dataGaName":775,"dataGaLocation":1152},{"text":1278,"config":1279},"Agile development",{"href":1280,"dataGaName":1281,"dataGaLocation":1152},"/solutions/agile-delivery/","agile delivery",{"text":1283,"config":1284},"SCM",{"href":787,"dataGaName":1285,"dataGaLocation":1152},"source code management",{"text":1231,"config":1287},{"href":780,"dataGaName":1288,"dataGaLocation":1152},"continuous integration & delivery",{"text":1290,"config":1291},"Value stream management",{"href":830,"dataGaName":1292,"dataGaLocation":1152},"value stream management",{"text":1236,"config":1294},{"href":1295,"dataGaName":1239,"dataGaLocation":1152},"/solutions/gitops/",{"text":840,"config":1297},{"href":843,"dataGaName":844,"dataGaLocation":1152},{"text":1299,"config":1300},"Small business",{"href":849,"dataGaName":850,"dataGaLocation":1152},{"text":1302,"config":1303},"Public sector",{"href":855,"dataGaName":856,"dataGaLocation":1152},{"text":1305,"config":1306},"Education",{"href":1307,"dataGaName":1308,"dataGaLocation":1152},"/solutions/education/","education",{"text":1310,"config":1311},"Financial services",{"href":1312,"dataGaName":1313,"dataGaLocation":1152},"/solutions/finance/","financial services",{"title":863,"links":1315},[1316,1318,1320,1322,1325,1327,1330,1332,1334,1336,1338,1340,1342,1344],{"text":876,"config":1317},{"href":878,"dataGaName":879,"dataGaLocation":1152},{"text":881,"config":1319},{"href":883,"dataGaName":884,"dataGaLocation":1152},{"text":886,"config":1321},{"href":888,"dataGaName":889,"dataGaLocation":1152},{"text":891,"config":1323},{"href":893,"dataGaName":1324,"dataGaLocation":1152},"docs",{"text":914,"config":1326},{"href":916,"dataGaName":917,"dataGaLocation":1152},{"text":1328,"config":1329},"What's new",{"href":974,"dataGaName":975,"dataGaLocation":1152},{"text":909,"config":1331},{"href":911,"dataGaName":912,"dataGaLocation":1152},{"text":928,"config":1333},{"href":930,"dataGaName":931,"dataGaLocation":1152},{"text":936,"config":1335},{"href":938,"dataGaName":939,"dataGaLocation":1152},{"text":941,"config":1337},{"href":943,"dataGaName":944,"dataGaLocation":1152},{"text":946,"config":1339},{"href":948,"dataGaName":949,"dataGaLocation":1152},{"text":951,"config":1341},{"href":953,"dataGaName":954,"dataGaLocation":1152},{"text":956,"config":1343},{"href":958,"dataGaName":959,"dataGaLocation":1152},{"text":961,"config":1345},{"href":963,"dataGaName":964,"dataGaLocation":1152},{"title":977,"links":1347},[1348,1350,1352,1354,1356,1358,1362,1367,1369,1371,1373],{"text":985,"config":1349},{"href":987,"dataGaName":979,"dataGaLocation":1152},{"text":990,"config":1351},{"href":992,"dataGaName":993,"dataGaLocation":1152},{"text":998,"config":1353},{"href":1000,"dataGaName":1001,"dataGaLocation":1152},{"text":1003,"config":1355},{"href":1005,"dataGaName":1006,"dataGaLocation":1152},{"text":1008,"config":1357},{"href":1010,"dataGaName":1011,"dataGaLocation":1152},{"text":1359,"config":1360},"Sustainability",{"href":1361,"dataGaName":1359,"dataGaLocation":1152},"/sustainability/",{"text":1363,"config":1364},"Diversity, inclusion and belonging (DIB)",{"href":1365,"dataGaName":1366,"dataGaLocation":1152},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":1013,"config":1368},{"href":1015,"dataGaName":1016,"dataGaLocation":1152},{"text":1023,"config":1370},{"href":1025,"dataGaName":1026,"dataGaLocation":1152},{"text":1028,"config":1372},{"href":1030,"dataGaName":1031,"dataGaLocation":1152},{"text":1374,"config":1375},"Modern Slavery Transparency Statement",{"href":1376,"dataGaName":1377,"dataGaLocation":1152},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1379},[1380,1383,1386],{"text":1381,"config":1382},"Terms",{"href":1204,"dataGaName":1205,"dataGaLocation":1152},{"text":1384,"config":1385},"Cookies",{"dataGaName":1214,"dataGaLocation":1152,"id":1215,"isOneTrustButton":328},{"text":1387,"config":1388},"Privacy",{"href":1209,"dataGaName":1210,"dataGaLocation":1152},[1390],{"id":1391,"title":1392,"body":690,"config":1393,"content":1395,"description":690,"extension":1399,"meta":1400,"navigation":328,"path":1401,"seo":1402,"stem":1403,"__hash__":1404},"blogAuthors/en-us/blog/authors/david-oregan.yml","David Oregan",{"template":1394},"BlogAuthor",{"name":7,"config":1396},{"headshot":1397,"ctfId":1398},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659853/Blog/Author%20Headshots/oregand-headshot.png","oregand","yml",{},"/en-us/blog/authors/david-oregan",{},"en-us/blog/authors/david-oregan","CX5gLc3Gs5FrmvpMNVkBtC5zRi3vj8l3wJGnW0iSa6Y",[1406,1415,1423],{"title":1407,"description":1408,"heroImage":1409,"category":686,"date":1410,"authors":1411,"slug":1414,"externalUrl":690},"Confidential AI for GitLab Self-Hosted","Give developers AI coding agents in GitLab Duo without source code leaving a hardware-encrypted boundary — no GPUs needed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-08-06",[1412,1413],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1416,"description":1417,"heroImage":1418,"category":686,"date":1419,"authors":1420,"slug":1422,"externalUrl":690},"Green DevOps: Why carbon measurement belongs in your CI/CD pipeline","CI/CD pipelines have a hidden carbon cost. Here's why measuring it matters, and how you can get started with Eco CI and Carmen in GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-07-09",[1421],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1424,"description":1425,"heroImage":1426,"category":686,"date":1427,"authors":1428,"slug":1430,"externalUrl":690},"How to build CI/CD observability at scale","This practical guide to GitLab pipeline analytics helps self-managed users gain operational insights using Prometheus and Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-28",[1429],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1432},[1433,1447,1459,1471],{"id":1434,"categories":1435,"header":1437,"text":1438,"button":1439,"image":1444},"ai-modernization",[1436],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1440,"config":1441},"Get your AI maturity score",{"href":1442,"dataGaName":1443,"dataGaLocation":917},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1445},{"src":1446},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1448,"categories":1449,"header":1451,"text":1438,"button":1452,"image":1456},"devops-modernization",[1450,1254],"product","Are you just managing tools or shipping innovation?",{"text":1453,"config":1454},"Get your DevOps maturity score",{"href":1455,"dataGaName":1443,"dataGaLocation":917},"/assessments/devops-modernization-assessment/",{"config":1457},{"src":1458},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1460,"categories":1461,"header":1463,"text":1438,"button":1464,"image":1468},"security-modernization",[1462],"security","Are you trading speed for security?",{"text":1465,"config":1466},"Get your security maturity score",{"href":1467,"dataGaName":1443,"dataGaLocation":917},"/assessments/security-modernization-assessment/",{"config":1469},{"src":1470},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1472,"paths":1473,"header":1476,"text":1477,"button":1478,"image":1483},"github-azure-migration",[1474,1475],"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":1479,"config":1480},"See how GitLab compares to GitHub",{"href":1481,"dataGaName":1482,"dataGaLocation":917},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1484},{"src":1458},{"header":1486,"blurb":1487,"button":1488,"secondaryButton":1493},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1489,"config":1490},"Get your free trial",{"href":1491,"dataGaName":716,"dataGaLocation":1492},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1190,"config":1494},{"href":1042,"dataGaName":721,"dataGaLocation":1492},1786803772145]