[{"data":1,"prerenderedAt":1278},["ShallowReactive",2],{"/blog/resolving-merge-conflicts-from-the-gitlab-ui":3,"navigation-en-us":494,"banner-en-us":921,"footer-en-us":931,"blog-post-authors-en-us-Sean McGivern":1174,"blog-related-posts-en-us-resolving-merge-conflicts-from-the-gitlab-ui":1190,"blog-promotions-en-us":1214,"next-steps-en-us":1268},{"id":4,"title":5,"authors":6,"body":8,"category":465,"date":466,"description":467,"extension":468,"externalUrl":469,"faq":469,"featured":470,"heroImage":471,"meta":472,"navigation":484,"path":485,"seo":486,"slug":490,"stem":491,"tags":469,"template":492,"updatedDate":469,"__hash__":493},"blogPosts/en-us/blog/resolving-merge-conflicts-from-the-gitlab-ui.md","Resolving Merge Conflicts from the GitLab UI",[7],"Sean McGivern",{"type":9,"value":10,"toc":447},"minimark",[11,15,18,28,33,36,41,61,80,93,105,109,112,120,123,127,130,200,215,219,222,229,232,238,244,250,254,257,292,301,337,341,349,377,380,384,392,396,405,409,418,422,434,443],[12,13,14],"p",{},"Merge conflicts can be very annoying for both merge request authors and\nreviewers. As an author, I just want my merge request to be merged. But the\nreviewer might not be in the same time zone as me and by the time they review\nmy changes, I have a merge conflict. I then need to fix it and pass the merge\nrequest back to them, which is a lot of busy work for something that could be\nfairly trivial to fix.",[12,16,17],{},"Similarly, as a reviewer, I want merge requests to be accepted when they're\nready. I don't want to spend my time checking out the author's branch, fixing\nthe conflicts, and pushing back; and I don't particularly like waiting around\nfor them to fix it. As an author or a reviewer, I just want to be able to have\nthe merge request accepted, and move on to the next thing. That's why understanding the methods of resolving conflicts is crucial. Fortunately, GitLab has a few ways of resolving conflicts from the GitLab UI.",[12,19,20,21,27],{},"In GitLab 8.11, we\n",[22,23,26],"a",{"href":24,"rel":25},"https://docs.gitlab.com/releases/#merge-conflict-resolution",[],"introduced the ability to resolve merge conflicts in the UI",". This\npost describes the background for the feature, how it works, and what we're\nplanning to do next with it.",[29,30,32],"h2",{"id":31},"what-is-a-merge-conflict","What is a merge conflict?",[12,34,35],{},"A merge conflict is when a merge can't be performed cleanly between two versions\nof the same file. An error message\nmay appear, indicating the conflict is too complex.",[37,38,40],"h3",{"id":39},"wait-whats-a-merge","Wait, what's a merge?",[12,42,43,44,49,50,55,56,60],{},"A merge is a way of combining two sets of changes made in different branches. In\nGitLab, we handle this with ",[22,45,48],{"href":46,"rel":47},"https://docs.gitlab.com/ce/user/project/merge_requests/",[],"Merge Requests",", which are requests to merge\nthe changes we've made to a file (or a group of files), from a ",[22,51,54],{"href":52,"rel":53},"https://docs.gitlab.com/gitlab-basics/feature_branch_workflow/",[],"feature\nbranch"," into another branch, for example, ",[57,58,59],"code",{},"master",".",[12,62,63,64,67,68,70,71,73,74,76,77,79],{},"When the merge request is merged, the changes from ",[57,65,66],{},"new-feature"," are added to\n",[57,69,59],{},". This happens by looking at all of the changes made in the ",[57,72,59],{}," branch since\nthe ",[57,75,66],{}," branch was created, and all the changes made in ",[57,78,66],{},",\nand applying them to the files changed.",[12,81,82,83,85,86,88,89,60],{},"Most of the time, Git can do this automatically, but sometimes it can't. For\ninstance, if we changed a line of code in our ",[57,84,66],{}," branch, but that line was\nalso changed in ",[57,87,59],{},", Git doesn't know which line to accept. When this happens, someone needs to manually tell Git which line\nto use, which creates a ",[90,91,92],"strong",{},"merge conflict",[12,94,95,98,99,104],{},[90,96,97],{},"Note:"," for this post, we will just concentrate on conflicts within a file. However,\nrenames and deletions can also cause conflicts, and we\n",[22,100,103],{"href":101,"rel":102},"https://gitlab.com/gitlab-org/gitlab-ce/issues/20665",[],"plan on supporting those"," in the future.",[29,106,108],{"id":107},"why-are-merge-conflicts-a-problem","Why are merge conflicts a problem?",[12,110,111],{},"They're really annoying!",[12,113,114,115,119],{},"When there's a conflict in a ",[22,116,118],{"href":117},"/topics/version-control/","version control"," system, a merge request can't be merged without manual\nintervention.",[12,121,122],{},"If you can't resolve complex merge conflicts within GitLab, that means that any merge\nrequest with a conflict needs to be checked out locally, resolved locally,\npushed back, and merged. That's a hassle and can't be done without having some\nGit tools installed locally. At GitLab, we want\neveryone to be able to collaborate on all digital content, and that\nmeans not having to install special tools whenever possible.",[37,124,126],{"id":125},"types-of-conflict-resolution","Types of conflict resolution",[12,128,129],{},"There are several methods of resolving conflicts:",[131,132,133,145,166],"ol",{},[134,135,136,137,144],"li",{},"Just pick one version, and use that. This is often the case with generated\nfiles. One example is the ",[22,138,141],{"href":139,"rel":140},"http://guides.rubyonrails.org/active_record_migrations.html#what-are-schema-files-for-questionmark",[],[57,142,143],{},"schema.rb"," file in a Rails app.\nConflicts on the schema version line are common, but we (almost) always want\nthe latest version.",[134,146,147,148,153,154,159,160,165],{},"Keep the lines of code from both versions. A great example of this is the\n",[22,149,152],{"href":150,"rel":151},"https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG.md",[],"GitLab CE CHANGELOG file",", which is a\n",[22,155,158],{"href":156,"rel":157},"https://gitlab.com/gitlab-org/gitlab-ce/issues/17826",[],"frequent source of merge conflicts",". We're working on\n",[22,161,164],{"href":162,"rel":163},"https://gitlab.com/gitlab-org/release-tools/merge_requests/29",[],"tooling to help with this",", but that's specific to\nGitLab rather than applicable to every project.",[134,167,168,169,175,178,179,184,186,187,192,194,195],{},"Write our own resolution. For instance, if we started with the sentence:",[170,171,172],"blockquote",{},[12,173,174],{},"There are two versions of GitLab: CE and EE",[176,177],"br",{},"I might think that those acronyms should be spelled out:",[170,180,181],{},[12,182,183],{},"There are two versions of GitLab: Community Edition (CE) and Enterprise Edition (EE)",[176,185],{},"And you might think that the sentence needs some closing punctuation:",[170,188,189],{},[12,190,191],{},"There are two versions of GitLab: CE and EE.",[176,193],{},"Because conflicts are based on lines, there's no way to automatically pick\nboth of those changes. We can do so manually, though:",[170,196,197],{},[12,198,199],{},"There are two versions of GitLab: Community Edition (CE) and Enterprise Edition (EE).",[12,201,202,203,208,209,214],{},"At present, the conflict resolution support in GitLab is only really useful for\nresolving the first type of conflict. The ",[22,204,207],{"href":205,"rel":206},"https://gitlab.pavlovia.org/help/user/project/merge_requests/resolve_conflicts.md",[],"merge conflict resolution editor"," allows for more complex ",[22,210,213],{"href":211,"rel":212},"https://docs.gitlab.com/user/project/merge_requests/conflicts/",[],"conflicts"," to be resolved by manually modifying a file from the GitLab interface.",[29,216,218],{"id":217},"how-do-we-resolve-them","How do we resolve them?",[12,220,221],{},"When a merge request can have its conflicts resolved within GitLab, it will have\na link within the merge box to 'resolve these conflicts':",[12,223,224],{},[225,226],"img",{"alt":227,"src":228},"The 'resolve these conflicts' link on a merge request","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398962/blog/Content%20Images/resolving-merge-conflicts-from-the-gitlab-ui/mr-widget.png",[12,230,231],{},"Clicking that link will show a list of files with conflicts, with conflict sections\nhighlighted as 'our changes' (the changes in the merge request's source branch)\nand 'their changes' (the changes in the merge request's target branch):",[12,233,234],{},[225,235],{"alt":236,"src":237},"Some example merge conflicts","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398961/blog/Content%20Images/resolving-merge-conflicts-from-the-gitlab-ui/merge-conflicts.png",[12,239,240,241,243],{},"Here's an example of a more complex merge conflict in a ",[57,242,143],{}," that I resolved on the GitLab CE\nproject:",[12,245,246],{},[225,247],{"alt":248,"src":249},"Resolving a merge conflict","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782405559/site/Content%20Images/8_11/resolve_mc.gif",[37,251,253],{"id":252},"how-does-that-work","How does that work?",[12,255,256],{},"The current implementation, at a high level, works like this:",[131,258,259,267,275,278,281,289],{},[134,260,261,262,60],{},"If a merge request has conflicts, GitLab gets a list of the\n",[22,263,266],{"href":264,"rel":265},"http://www.rubydoc.info/github/libgit2/rugged/Rugged/Index#conflicts-instance_method",[],"files with merge conflicts",[134,268,269,270,60],{},"For each file, it then\n",[22,271,274],{"href":272,"rel":273},"http://www.rubydoc.info/github/libgit2/rugged/Rugged/Index#merge_file-instance_method",[],"generates a merged file with conflict markers",[134,276,277],{},"GitLab parses those conflict markers out and presents them to the UI as\nsections: context, our side of the conflict, their side of the conflict,\ncontext, etc.",[134,279,280],{},"When the UI passes the section IDs back, we do the same thing. This time,\nGitLab only keeps the sections the user selected, along with all context\nsections.",[134,282,283,284,60],{},"GitLab joins the resolved lines together to create a resolved file, and\n",[22,285,288],{"href":286,"rel":287},"http://www.rubydoc.info/github/libgit2/rugged/Rugged/Index#add-instance_method",[],"adds it to the Git index",[134,290,291],{},"Finally, we write that index as a merge commit to the source branch.",[12,293,294,295,297,298,300],{},"If the source branch is ",[57,296,66],{}," and the target branch is ",[57,299,59],{},", then\nthis does basically the same thing as running:",[302,303,308],"pre",{"className":304,"code":305,"language":306,"meta":307,"style":307},"language-shell shiki shiki-themes github-light","git checkout new-feature\ngit merge master\n","shell","",[57,309,310,326],{"__ignoreMap":307},[311,312,315,319,323],"span",{"class":313,"line":314},"line",1,[311,316,318],{"class":317},"s7eDp","git",[311,320,322],{"class":321},"sYBdl"," checkout",[311,324,325],{"class":321}," new-feature\n",[311,327,329,331,334],{"class":313,"line":328},2,[311,330,318],{"class":317},[311,332,333],{"class":321}," merge",[311,335,336],{"class":321}," master\n",[37,338,340],{"id":339},"why-cant-some-conflicts-be-resolved-in-gitlab","Why can't some conflicts be resolved in GitLab?",[12,342,343,344,348],{},"The implementation above produces a number of constraints (for the most\nup-to-date list, please see the\n",[22,345,347],{"href":211,"rel":346},[],"merge conflict resolution documentation",":",[131,350,351,358,365,374],{},[134,352,353,354,60],{},"If the file contains conflict markers that mean we can't parse the file contents\nunambiguously, we can't show the sections. We will, however, be able to allow\n",[22,355,357],{"href":356},"#an-editor","resolving those conflicts in an editor",[134,359,360,361,104],{},"If the file is a binary file, we can't parse the file for conflict markers\nbecause they are only added to text files. Again, we plan to\n",[22,362,364],{"href":363},"#binary-files","allow resolving conflicts in binary files",[134,366,367,368,373],{},"If the file ",[22,369,372],{"href":370,"rel":371},"https://gitlab.com/gitlab-org/gitlab-ce/issues/21247",[],"isn't in a UTF-8 compatible encoding",", we can't allow\nresolving it because we pass data back and forth as JSON.",[134,375,376],{},"If the file is too large (over 200 KB), we avoid parsing it.",[12,378,379],{},"Because all conflicts must be resolved at once, if any of the conflicts for a\nmerge request can't be resolved in the GitLab UI, then the conflicts must be\nresolved manually.",[29,381,383],{"id":382},"whats-next","What's next?",[12,385,386,387,60],{},"There are plenty of places for improving our current implementation, and we'd\nlove to hear of ones we haven't thought of. Here are three obvious ones already\nin our ",[22,388,391],{"href":389,"rel":390},"https://gitlab.com/gitlab-org/gitlab-ce/issues",[],"issue tracker",[37,393,395],{"id":394},"an-inline-editor","An inline editor!",[12,397,398,399,404],{},"The most obvious improvement is to allow\n",[22,400,403],{"href":401,"rel":402},"https://gitlab.com/gitlab-org/gitlab-ce/issues/20344",[],"editing the conflict resolution",". This is closer to the experience on\nthe command line, with the conflict markers present in the file. It will also\ncover most of the problem cases listed above with the current approach.",[37,406,408],{"id":407},"binary-files","Binary files!",[12,410,411,412,417],{},"In addition to this, as binary files are typically not manually mergeable, we\ncould just ",[22,413,416],{"href":414,"rel":415},"https://gitlab.com/gitlab-org/gitlab-ce/issues/20664",[],"show both file versions",", and ask which one to use. This will work\nbest for images, but can support all binary files.",[37,419,421],{"id":420},"renames","Renames!",[12,423,424,425,427,428,433],{},"Incompatible renames are detected as conflicts by the ",[57,426,318],{}," command line tool,\nbut not by the library we use at GitLab. We can ",[22,429,432],{"href":430,"rel":431},"https://gitlab.com/gitlab-org/gitlab-ce/issues/20345",[],"detect rename conflicts","\nourselves, it's just more work.",[12,435,436],{},[90,437,438,439,60],{},"For the latest information on how to resolve merge conflicts in GitLab, check out our ",[22,440,442],{"href":211,"rel":441},[],"documentation",[444,445,446],"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 .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":307,"searchDepth":328,"depth":328,"links":448},[449,453,456,460],{"id":31,"depth":328,"text":32,"children":450},[451],{"id":39,"depth":452,"text":40},3,{"id":107,"depth":328,"text":108,"children":454},[455],{"id":125,"depth":452,"text":126},{"id":217,"depth":328,"text":218,"children":457},[458,459],{"id":252,"depth":452,"text":253},{"id":339,"depth":452,"text":340},{"id":382,"depth":328,"text":383,"children":461},[462,463,464],{"id":394,"depth":452,"text":395},{"id":407,"depth":452,"text":408},{"id":420,"depth":452,"text":421},"company","2016-09-06","Learn how GitLab's merge conflict resolution feature works and why we introduced it.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749666760/Blog/Hero%20Images/merge-conflicts.png",{"excerpt":473},{"type":9,"value":474},[475,477,479],[12,476,14],{},[12,478,17],{},[12,480,20,481,27],{},[22,482,26],{"href":24,"rel":483},[],true,"/en-us/blog/resolving-merge-conflicts-from-the-gitlab-ui",{"title":5,"description":467,"ogTitle":5,"ogDescription":467,"noIndex":470,"ogImage":471,"ogUrl":487,"ogSiteName":488,"ogType":489,"canonicalUrls":487},"https://about.gitlab.com/blog/resolving-merge-conflicts-from-the-gitlab-ui","https://about.gitlab.com","article","resolving-merge-conflicts-from-the-gitlab-ui","en-us/blog/resolving-merge-conflicts-from-the-gitlab-ui","BlogPost","-LgGOrQt_30jJbHSTxd_H9Ir7WOnehXidJrmzOhCOBw",{"logo":495,"freeTrial":500,"sales":505,"login":510,"items":515,"search":841,"minimal":872,"duo":891,"switchNav":900,"pricingDeployment":911},{"config":496},{"href":497,"dataGaName":498,"dataGaLocation":499},"/","gitlab logo","header",{"text":501,"config":502},"Get free trial",{"href":503,"dataGaName":504,"dataGaLocation":499},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":506,"config":507},"Request a demo",{"href":508,"dataGaName":509,"dataGaLocation":499},"/sales/?contact-topic=request-demo","sales",{"text":511,"config":512},"Sign in",{"href":513,"dataGaName":514,"dataGaLocation":499},"https://gitlab.com/users/sign_in/","sign in",[516,545,645,650,764,819],{"text":517,"config":518,"menu":520},"Platform",{"dataNavLevelOne":519},"platform",{"type":521,"columns":522},"cards",[523,529,537],{"title":517,"description":524,"link":525},"The intelligent orchestration platform for DevSecOps",{"text":526,"config":527},"Explore our Platform",{"href":528,"dataGaName":519,"dataGaLocation":499},"/platform/",{"title":530,"description":531,"link":532},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":533,"config":534},"Meet GitLab Duo",{"href":535,"dataGaName":536,"dataGaLocation":499},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":538,"description":539,"link":540},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":541,"config":542},"Learn more",{"href":543,"dataGaName":544,"dataGaLocation":499},"/why-gitlab/","why gitlab",{"text":546,"left":484,"config":547,"menu":549},"Product",{"dataNavLevelOne":548},"solutions",{"type":550,"link":551,"columns":555,"feature":624},"lists",{"text":552,"config":553},"View all Solutions",{"href":554,"dataGaName":548,"dataGaLocation":499},"/solutions/",[556,580,603],{"title":557,"description":558,"link":559,"items":564},"Automation","CI/CD and automation to accelerate deployment",{"config":560},{"icon":561,"href":562,"dataGaName":563,"dataGaLocation":499},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[565,569,572,576],{"text":566,"config":567},"CI/CD",{"href":568,"dataGaLocation":499,"dataGaName":566},"/solutions/continuous-integration/",{"text":530,"config":570},{"href":535,"dataGaLocation":499,"dataGaName":571},"gitlab duo agent platform - product menu",{"text":573,"config":574},"Source Code Management",{"href":575,"dataGaLocation":499,"dataGaName":573},"/solutions/source-code-management/",{"text":577,"config":578},"Automated Software Delivery",{"href":562,"dataGaLocation":499,"dataGaName":579},"Automated software delivery",{"title":581,"description":582,"link":583,"items":588},"Security","Deliver code faster without compromising security",{"config":584},{"href":585,"dataGaName":586,"dataGaLocation":499,"icon":587},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[589,593,598],{"text":590,"config":591},"Application Security Testing",{"href":585,"dataGaName":592,"dataGaLocation":499},"Application security testing",{"text":594,"config":595},"Software Supply Chain Security",{"href":596,"dataGaLocation":499,"dataGaName":597},"/solutions/supply-chain/","Software supply chain security",{"text":599,"config":600},"Software Compliance",{"href":601,"dataGaName":602,"dataGaLocation":499},"/solutions/software-compliance/","software compliance",{"title":604,"link":605,"items":610},"Measurement",{"config":606},{"icon":607,"href":608,"dataGaName":609,"dataGaLocation":499},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[611,615,619],{"text":612,"config":613},"Visibility & Measurement",{"href":608,"dataGaLocation":499,"dataGaName":614},"Visibility and Measurement",{"text":616,"config":617},"Value Stream Management",{"href":618,"dataGaLocation":499,"dataGaName":616},"/solutions/value-stream-management/",{"text":620,"config":621},"Analytics & Insights",{"href":622,"dataGaLocation":499,"dataGaName":623},"/solutions/analytics-and-insights/","Analytics and insights",{"title":625,"type":550,"items":626},"GitLab for",[627,633,639],{"text":628,"config":629},"Enterprise",{"icon":630,"href":631,"dataGaLocation":499,"dataGaName":632},"Building","/enterprise/","enterprise",{"text":634,"config":635},"Small Business",{"icon":636,"href":637,"dataGaLocation":499,"dataGaName":638},"Work","/small-business/","small business",{"text":640,"config":641},"Public Sector",{"icon":642,"href":643,"dataGaLocation":499,"dataGaName":644},"Organization","/solutions/public-sector/","public sector",{"text":646,"config":647},"Pricing",{"href":648,"dataGaName":649,"dataGaLocation":499,"dataNavLevelOne":649},"/pricing/","pricing",{"text":651,"config":652,"menu":654},"Resources",{"dataNavLevelOne":653},"resources",{"type":550,"link":655,"columns":659,"feature":753},{"text":656,"config":657},"View all resources",{"href":658,"dataGaName":653,"dataGaLocation":499},"/resources/",[660,693,720],{"title":661,"items":662},"Getting started",[663,668,673,678,683,688],{"text":664,"config":665},"Install",{"href":666,"dataGaName":667,"dataGaLocation":499},"/install/","install",{"text":669,"config":670},"Quick start guides",{"href":671,"dataGaName":672,"dataGaLocation":499},"/get-started/","quick setup checklists",{"text":674,"config":675},"Learn",{"href":676,"dataGaLocation":499,"dataGaName":677},"https://university.gitlab.com/","learn",{"text":679,"config":680},"Product documentation",{"href":681,"dataGaName":682,"dataGaLocation":499},"https://docs.gitlab.com/","product documentation",{"text":684,"config":685},"Best practice videos",{"href":686,"dataGaName":687,"dataGaLocation":499},"/getting-started-videos/","best practice videos",{"text":689,"config":690},"Integrations",{"href":691,"dataGaName":692,"dataGaLocation":499},"/integrations/","integrations",{"title":694,"items":695},"Discover",[696,701,706,711,715],{"text":697,"config":698},"Customer success stories",{"href":699,"dataGaName":700,"dataGaLocation":499},"/customers/","customer success stories",{"text":702,"config":703},"Blog",{"href":704,"dataGaName":705,"dataGaLocation":499},"/blog/","blog",{"text":707,"config":708},"Demo Hub",{"href":709,"dataGaName":710,"dataGaLocation":499},"/demo-hub/","demo hub",{"text":712,"config":713},"The Source",{"href":714,"dataGaName":705,"dataGaLocation":499},"/the-source/",{"text":716,"config":717},"Remote",{"href":718,"dataGaName":719,"dataGaLocation":499},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":721,"items":722},"Connect",[723,728,733,738,743,748],{"text":724,"config":725},"GitLab Services",{"href":726,"dataGaName":727,"dataGaLocation":499},"/services/","services",{"text":729,"config":730},"Contribute",{"href":731,"dataGaName":732,"dataGaLocation":499},"https://contributors.gitlab.com","contribute",{"text":734,"config":735},"Community",{"href":736,"dataGaName":737,"dataGaLocation":499},"/community/","community",{"text":739,"config":740},"Forum",{"href":741,"dataGaName":742,"dataGaLocation":499},"https://forum.gitlab.com/","forum",{"text":744,"config":745},"Events",{"href":746,"dataGaName":747,"dataGaLocation":499},"/events/","events",{"text":749,"config":750},"Partners",{"href":751,"dataGaName":752,"dataGaLocation":499},"/partners/","partners",{"config":754,"title":757,"text":758,"link":759},{"background":755,"textColor":756},"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":760,"config":761},"Read the latest",{"href":762,"dataGaName":763,"dataGaLocation":499},"/whats-new/","whats new",{"text":765,"config":766,"menu":767},"Company",{"dataNavLevelOne":465},{"type":550,"columns":768},[769],{"items":770},[771,776,782,784,789,794,799,804,809,814],{"text":772,"config":773},"About",{"href":774,"dataGaName":775,"dataGaLocation":499},"/company/","about",{"text":777,"config":778,"footerGa":781},"Jobs",{"href":779,"dataGaName":780,"dataGaLocation":499},"/jobs/","jobs",{"dataGaName":780},{"text":744,"config":783},{"href":746,"dataGaName":747,"dataGaLocation":499},{"text":785,"config":786},"Leadership",{"href":787,"dataGaName":788,"dataGaLocation":499},"/company/team/e-group/","leadership",{"text":790,"config":791},"Handbook",{"href":792,"dataGaName":793,"dataGaLocation":499},"https://handbook.gitlab.com/","handbook",{"text":795,"config":796},"Investor relations",{"href":797,"dataGaName":798,"dataGaLocation":499},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":800,"config":801},"Trust Center",{"href":802,"dataGaName":803,"dataGaLocation":499},"/security/","trust center",{"text":805,"config":806},"AI Transparency Center",{"href":807,"dataGaName":808,"dataGaLocation":499},"/ai-transparency-center/","ai transparency center",{"text":810,"config":811},"Newsletter",{"href":812,"dataGaName":813,"dataGaLocation":499},"/company/contact/#contact-forms","newsletter",{"text":815,"config":816},"Press",{"href":817,"dataGaName":818,"dataGaLocation":499},"/press/","press",{"text":820,"config":821,"menu":822},"Contact us",{"dataNavLevelOne":465},{"type":550,"columns":823},[824],{"items":825},[826,831,836],{"text":827,"config":828},"Talk to sales",{"href":829,"dataGaName":830,"dataGaLocation":499},"/sales/","talk to sales",{"text":832,"config":833},"Support portal",{"href":834,"dataGaName":835,"dataGaLocation":499},"https://support.gitlab.com/hc/en-us","support portal",{"text":837,"config":838},"Customer portal",{"href":839,"dataGaName":840,"dataGaLocation":499},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":842,"login":843,"suggestions":850},"Close",{"text":844,"link":845},"To search repositories and projects, login to",{"text":846,"config":847},"gitlab.com",{"href":513,"dataGaName":848,"dataGaLocation":849},"search login","search",{"text":851,"default":852},"Suggestions",[853,855,859,861,865,869],{"text":530,"config":854},{"href":535,"dataGaName":530,"dataGaLocation":849},{"text":856,"config":857},"Code Suggestions (AI)",{"href":858,"dataGaName":856,"dataGaLocation":849},"/solutions/code-suggestions/",{"text":566,"config":860},{"href":568,"dataGaName":566,"dataGaLocation":849},{"text":862,"config":863},"GitLab on AWS",{"href":864,"dataGaName":862,"dataGaLocation":849},"/partners/technology-partners/aws/",{"text":866,"config":867},"GitLab on Google Cloud",{"href":868,"dataGaName":866,"dataGaLocation":849},"/partners/technology-partners/google-cloud-platform/",{"text":870,"config":871},"Why GitLab?",{"href":543,"dataGaName":870,"dataGaLocation":849},{"freeTrial":873,"mobileIcon":878,"desktopIcon":883,"secondaryButton":886},{"text":874,"config":875},"Start free trial",{"href":876,"dataGaName":504,"dataGaLocation":877},"https://gitlab.com/-/trials/new/","nav",{"altText":879,"config":880},"Gitlab Icon",{"src":881,"dataGaName":882,"dataGaLocation":877},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":879,"config":884},{"src":885,"dataGaName":882,"dataGaLocation":877},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":887,"config":888},"Get Started",{"href":889,"dataGaName":890,"dataGaLocation":877},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":892,"mobileIcon":896,"desktopIcon":898},{"text":893,"config":894},"Learn more about GitLab Duo",{"href":535,"dataGaName":895,"dataGaLocation":877},"gitlab duo",{"altText":879,"config":897},{"src":881,"dataGaName":882,"dataGaLocation":877},{"altText":879,"config":899},{"src":885,"dataGaName":882,"dataGaLocation":877},{"button":901,"mobileIcon":906,"desktopIcon":908},{"text":902,"config":903},"/switch",{"href":904,"dataGaName":905,"dataGaLocation":877},"#contact","switch",{"altText":879,"config":907},{"src":881,"dataGaName":882,"dataGaLocation":877},{"altText":879,"config":909},{"src":910,"dataGaName":882,"dataGaLocation":877},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":912,"mobileIcon":917,"desktopIcon":919},{"text":913,"config":914},"Back to pricing",{"href":648,"dataGaName":915,"dataGaLocation":877,"icon":916},"back to pricing","GoBack",{"altText":879,"config":918},{"src":881,"dataGaName":882,"dataGaLocation":877},{"altText":879,"config":920},{"src":885,"dataGaName":882,"dataGaLocation":877},{"title":922,"titleMobile":923,"button":924,"config":929},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":541,"config":925},{"href":926,"dataGaName":927,"dataGaLocation":928},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":930,"disabled":470},"release",{"data":932},{"text":933,"source":934,"edit":940,"contribute":945,"config":950,"items":955,"minimal":1163},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":935,"config":936},"View page source",{"href":937,"dataGaName":938,"dataGaLocation":939},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":941,"config":942},"Edit this page",{"href":943,"dataGaName":944,"dataGaLocation":939},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":946,"config":947},"Please contribute",{"href":948,"dataGaName":949,"dataGaLocation":939},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":951,"facebook":952,"youtube":953,"linkedin":954},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[956,1003,1055,1099,1131],{"title":646,"links":957,"subMenu":972},[958,962,967],{"text":959,"config":960},"View plans",{"href":648,"dataGaName":961,"dataGaLocation":939},"view plans",{"text":963,"config":964},"Why Premium?",{"href":965,"dataGaName":966,"dataGaLocation":939},"/pricing/premium/","why premium",{"text":968,"config":969},"Why Ultimate?",{"href":970,"dataGaName":971,"dataGaLocation":939},"/pricing/ultimate/","why ultimate",[973],{"title":974,"links":975},"Contact Us",[976,979,981,983,988,993,998],{"text":977,"config":978},"Contact sales",{"href":829,"dataGaName":509,"dataGaLocation":939},{"text":832,"config":980},{"href":834,"dataGaName":835,"dataGaLocation":939},{"text":837,"config":982},{"href":839,"dataGaName":840,"dataGaLocation":939},{"text":984,"config":985},"Status",{"href":986,"dataGaName":987,"dataGaLocation":939},"https://status.gitlab.com/","status",{"text":989,"config":990},"Terms of use",{"href":991,"dataGaName":992,"dataGaLocation":939},"/terms/","terms of use",{"text":994,"config":995},"Privacy statement",{"href":996,"dataGaName":997,"dataGaLocation":939},"/privacy/","privacy statement",{"text":999,"config":1000},"Cookie preferences",{"dataGaName":1001,"dataGaLocation":939,"id":1002,"isOneTrustButton":484},"cookie preferences","ot-sdk-btn",{"title":546,"links":1004,"subMenu":1013},[1005,1009],{"text":1006,"config":1007},"DevSecOps platform",{"href":528,"dataGaName":1008,"dataGaLocation":939},"devsecops platform",{"text":1010,"config":1011},"AI-Assisted Development",{"href":535,"dataGaName":1012,"dataGaLocation":939},"ai-assisted development",[1014],{"title":1015,"links":1016},"Topics",[1017,1022,1027,1032,1035,1040,1045,1050],{"text":1018,"config":1019},"CICD",{"href":1020,"dataGaName":1021,"dataGaLocation":939},"/topics/ci-cd/","cicd",{"text":1023,"config":1024},"GitOps",{"href":1025,"dataGaName":1026,"dataGaLocation":939},"/topics/gitops/","gitops",{"text":1028,"config":1029},"DevOps",{"href":1030,"dataGaName":1031,"dataGaLocation":939},"/topics/devops/","devops",{"text":1033,"config":1034},"Version Control",{"href":117,"dataGaName":118,"dataGaLocation":939},{"text":1036,"config":1037},"DevSecOps",{"href":1038,"dataGaName":1039,"dataGaLocation":939},"/topics/devsecops/","devsecops",{"text":1041,"config":1042},"Cloud Native",{"href":1043,"dataGaName":1044,"dataGaLocation":939},"/topics/cloud-native/","cloud native",{"text":1046,"config":1047},"AI for Coding",{"href":1048,"dataGaName":1049,"dataGaLocation":939},"/topics/devops/ai-for-coding/","ai for coding",{"text":1051,"config":1052},"Agentic AI",{"href":1053,"dataGaName":1054,"dataGaLocation":939},"/topics/agentic-ai/","agentic ai",{"title":1056,"links":1057},"Solutions",[1058,1060,1062,1067,1071,1074,1078,1081,1083,1086,1089,1094],{"text":590,"config":1059},{"href":585,"dataGaName":590,"dataGaLocation":939},{"text":579,"config":1061},{"href":562,"dataGaName":563,"dataGaLocation":939},{"text":1063,"config":1064},"Agile development",{"href":1065,"dataGaName":1066,"dataGaLocation":939},"/solutions/agile-delivery/","agile delivery",{"text":1068,"config":1069},"SCM",{"href":575,"dataGaName":1070,"dataGaLocation":939},"source code management",{"text":1018,"config":1072},{"href":568,"dataGaName":1073,"dataGaLocation":939},"continuous integration & delivery",{"text":1075,"config":1076},"Value stream management",{"href":618,"dataGaName":1077,"dataGaLocation":939},"value stream management",{"text":1023,"config":1079},{"href":1080,"dataGaName":1026,"dataGaLocation":939},"/solutions/gitops/",{"text":628,"config":1082},{"href":631,"dataGaName":632,"dataGaLocation":939},{"text":1084,"config":1085},"Small business",{"href":637,"dataGaName":638,"dataGaLocation":939},{"text":1087,"config":1088},"Public sector",{"href":643,"dataGaName":644,"dataGaLocation":939},{"text":1090,"config":1091},"Education",{"href":1092,"dataGaName":1093,"dataGaLocation":939},"/solutions/education/","education",{"text":1095,"config":1096},"Financial services",{"href":1097,"dataGaName":1098,"dataGaLocation":939},"/solutions/finance/","financial services",{"title":651,"links":1100},[1101,1103,1105,1107,1110,1112,1115,1117,1119,1121,1123,1125,1127,1129],{"text":664,"config":1102},{"href":666,"dataGaName":667,"dataGaLocation":939},{"text":669,"config":1104},{"href":671,"dataGaName":672,"dataGaLocation":939},{"text":674,"config":1106},{"href":676,"dataGaName":677,"dataGaLocation":939},{"text":679,"config":1108},{"href":681,"dataGaName":1109,"dataGaLocation":939},"docs",{"text":702,"config":1111},{"href":704,"dataGaName":705,"dataGaLocation":939},{"text":1113,"config":1114},"What's new",{"href":762,"dataGaName":763,"dataGaLocation":939},{"text":697,"config":1116},{"href":699,"dataGaName":700,"dataGaLocation":939},{"text":716,"config":1118},{"href":718,"dataGaName":719,"dataGaLocation":939},{"text":724,"config":1120},{"href":726,"dataGaName":727,"dataGaLocation":939},{"text":729,"config":1122},{"href":731,"dataGaName":732,"dataGaLocation":939},{"text":734,"config":1124},{"href":736,"dataGaName":737,"dataGaLocation":939},{"text":739,"config":1126},{"href":741,"dataGaName":742,"dataGaLocation":939},{"text":744,"config":1128},{"href":746,"dataGaName":747,"dataGaLocation":939},{"text":749,"config":1130},{"href":751,"dataGaName":752,"dataGaLocation":939},{"title":765,"links":1132},[1133,1135,1137,1139,1141,1143,1147,1152,1154,1156,1158],{"text":772,"config":1134},{"href":774,"dataGaName":465,"dataGaLocation":939},{"text":777,"config":1136},{"href":779,"dataGaName":780,"dataGaLocation":939},{"text":785,"config":1138},{"href":787,"dataGaName":788,"dataGaLocation":939},{"text":790,"config":1140},{"href":792,"dataGaName":793,"dataGaLocation":939},{"text":795,"config":1142},{"href":797,"dataGaName":798,"dataGaLocation":939},{"text":1144,"config":1145},"Sustainability",{"href":1146,"dataGaName":1144,"dataGaLocation":939},"/sustainability/",{"text":1148,"config":1149},"Diversity, inclusion and belonging (DIB)",{"href":1150,"dataGaName":1151,"dataGaLocation":939},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":800,"config":1153},{"href":802,"dataGaName":803,"dataGaLocation":939},{"text":810,"config":1155},{"href":812,"dataGaName":813,"dataGaLocation":939},{"text":815,"config":1157},{"href":817,"dataGaName":818,"dataGaLocation":939},{"text":1159,"config":1160},"Modern Slavery Transparency Statement",{"href":1161,"dataGaName":1162,"dataGaLocation":939},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1164},[1165,1168,1171],{"text":1166,"config":1167},"Terms",{"href":991,"dataGaName":992,"dataGaLocation":939},{"text":1169,"config":1170},"Cookies",{"dataGaName":1001,"dataGaLocation":939,"id":1002,"isOneTrustButton":484},{"text":1172,"config":1173},"Privacy",{"href":996,"dataGaName":997,"dataGaLocation":939},[1175],{"id":1176,"title":1177,"body":469,"config":1178,"content":1180,"description":469,"extension":1184,"meta":1185,"navigation":484,"path":1186,"seo":1187,"stem":1188,"__hash__":1189},"blogAuthors/en-us/blog/authors/sean-mcgivern.yml","Sean Mcgivern",{"template":1179},"BlogAuthor",{"name":7,"config":1181},{"headshot":1182,"ctfId":1183},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659488/Blog/Author%20Headshots/gitlab-logo-extra-whitespace.png","Sean-McGivern","yml",{},"/en-us/blog/authors/sean-mcgivern",{},"en-us/blog/authors/sean-mcgivern","XSLkuLncc0pKQoZdVKdAEaieWRiQ6dWRrY0c8bNtvWw",[1191,1199,1206],{"title":1192,"description":1193,"heroImage":1194,"category":465,"date":1195,"authors":1196,"slug":1198,"externalUrl":469},"Why GitLab signed the Open Weights and American AI Leadership letter","GitLab supports customer choice, data privacy, and AI model neutrality, empowering teams to run secure, cost-effective, local solutions.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1785333264/ww4mlighwlvvzgnmbe6w.png","2026-07-29",[1197],"Bill Staples","open-weight-model-letter",{"title":1200,"description":1201,"heroImage":1202,"category":465,"date":1203,"authors":1204,"slug":1205,"externalUrl":469},"GitLab Act 2","A letter to our customers and our investors.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1776362275/ozbwn9tk0dditpnfddlz.png","2026-05-11",[1197],"gitlab-act-2",{"title":1207,"description":1208,"heroImage":1209,"category":465,"date":1210,"authors":1211,"slug":1213,"externalUrl":469},"GitLab named a 2026 Omdia Universe Leader","Omdia's 2026 report on AI-assisted software development ranked 19 vendors. Here is what GitLab's top scores mean for engineering teams.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-13",[1212],"Rebecca Carter","gitlab-named-a-2026-omdia-universe-leader",{"promotions":1215},[1216,1230,1242,1254],{"id":1217,"categories":1218,"header":1220,"text":1221,"button":1222,"image":1227},"ai-modernization",[1219],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1223,"config":1224},"Get your AI maturity score",{"href":1225,"dataGaName":1226,"dataGaLocation":705},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1228},{"src":1229},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1231,"categories":1232,"header":1234,"text":1221,"button":1235,"image":1239},"devops-modernization",[1233,1039],"product","Are you just managing tools or shipping innovation?",{"text":1236,"config":1237},"Get your DevOps maturity score",{"href":1238,"dataGaName":1226,"dataGaLocation":705},"/assessments/devops-modernization-assessment/",{"config":1240},{"src":1241},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1243,"categories":1244,"header":1246,"text":1221,"button":1247,"image":1251},"security-modernization",[1245],"security","Are you trading speed for security?",{"text":1248,"config":1249},"Get your security maturity score",{"href":1250,"dataGaName":1226,"dataGaLocation":705},"/assessments/security-modernization-assessment/",{"config":1252},{"src":1253},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1255,"paths":1256,"header":1259,"text":1260,"button":1261,"image":1266},"github-azure-migration",[1257,1258],"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":1262,"config":1263},"See how GitLab compares to GitHub",{"href":1264,"dataGaName":1265,"dataGaLocation":705},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1267},{"src":1241},{"header":1269,"blurb":1270,"button":1271,"secondaryButton":1276},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1272,"config":1273},"Get your free trial",{"href":1274,"dataGaName":504,"dataGaLocation":1275},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":977,"config":1277},{"href":829,"dataGaName":509,"dataGaLocation":1275},1786803764981]