[{"data":1,"prerenderedAt":1293},["ShallowReactive",2],{"/blog/keep-git-history-clean-with-interactive-rebase":3,"navigation-en-us":505,"banner-en-us":932,"footer-en-us":942,"blog-post-authors-en-us-Tobias Günther":1187,"blog-related-posts-en-us-keep-git-history-clean-with-interactive-rebase":1203,"blog-promotions-en-us":1229,"next-steps-en-us":1283},{"id":4,"title":5,"authors":6,"body":8,"category":484,"date":485,"description":486,"extension":487,"externalUrl":488,"faq":488,"featured":489,"heroImage":490,"meta":491,"navigation":492,"path":493,"seo":494,"slug":498,"stem":499,"tags":500,"template":503,"updatedDate":488,"__hash__":504},"blogPosts/en-us/blog/keep-git-history-clean-with-interactive-rebase.md","How to keep your Git history clean with interactive rebase",[7],"Tobias Günther",{"type":9,"value":10,"toc":473},"minimark",[11,16,31,34,37,46,50,71,74,82,97,104,107,139,146,153,160,167,170,174,181,184,191,194,212,215,222,229,232,239,242,246,249,252,255,262,265,268,275,307,310,317,320,341,352,359,362,375,378,381,388,391,395,408,411,415,436,441,455,469],[12,13,15],"h2",{"id":14},"what-is-interactive-rebase","What is interactive rebase?",[17,18,19,20,25,26,30],"p",{},"Interactive ",[21,22,24],"a",{"href":23},"/solutions/source-code-management/","rebase",", or Git rebase interactive, is sometimes called the \"Swiss Army Knife\" of Git – because it contains so many different tools, for so many different use cases! However, there's one main, overarching use case: ",[27,28,29],"em",{},"cleaning up your local commit history",".",[17,32,33],{},"Mind the word \"local\": it should only be used for cleaning up your own, local commit history, for example before integrating one of your feature branches into a team branch. In contrast, it should NOT be used on commit history that has already been pushed and shared on a remote repository. Interactive rebase is one of those tools that \"rewrite\" Git history – and you shouldn't do this on commits that have already been shared with others.",[17,35,36],{},"With this little warning message out of the way, let's look at some practical examples!",[17,38,39,40,45],{},"Note: for easier visualization of the scenarios and workflows in this post, I’ve been using the ",[21,41,44],{"href":42,"rel":43},"https://www.git-tower.com/?utm_source=gitlab&utm_medium=guestpost&utm_campaign=interactive-rebase",[],"\"Tower\" Git desktop GUI"," in some of my screenshots.",[12,47,49],{"id":48},"correcting-an-old-commit-message-with-git-rebase-interactive","Correcting an old commit message with Git rebase interactive",[17,51,52,53,57,58,61,62,66,67,70],{},"Sometimes you notice a typo in an ",[54,55,56],"strong",{},"old commit message"," – or you've forgotten to mention something in the description that is noteworthy. If we were talking about the ",[27,59,60],{},"very last"," commit, we could have simply used the ",[63,64,65],"code",{},"--amend"," option of the ",[63,68,69],{},"git commit"," command. But for older commits you will have to use interactive rebase to change them after the fact.",[17,72,73],{},"Here's an example of a commit message gone horribly wrong that we want to correct:",[17,75,76,81],{},[77,78],"img",{"alt":79,"src":80},"A bad commit message that needs correction","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398506/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/bad-commit-message%402x.png","\nA bad commit message that needs correction",[17,83,84,85,88,89,92,93,96],{},"The first step in ",[27,86,87],{},"any"," Git interactive rebase session is to ",[54,90,91],{},"determine what part of commit history you want to manipulate",". To again take the above example: in order to change this bad commit we have to start the session at its ",[27,94,95],{},"parent"," commit.",[17,98,99,103],{},[77,100],{"alt":101,"src":102},"Starting our interactive rebase session","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398510/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/start-at-parent-commit%402x.png","\nStarting our interactive rebase session",[17,105,106],{},"We can now feed this starting commit's hash to the Git rebase interactive command:",[108,109,114],"pre",{"className":110,"code":111,"language":112,"meta":113,"style":113},"language-shell shiki shiki-themes github-light","$ git rebase -i 0023cddd\n","shell","",[63,115,116],{"__ignoreMap":113},[117,118,121,125,129,132,136],"span",{"class":119,"line":120},"line",1,[117,122,124],{"class":123},"s7eDp","$",[117,126,128],{"class":127},"sYBdl"," git",[117,130,131],{"class":127}," rebase",[117,133,135],{"class":134},"sYu0t"," -i",[117,137,138],{"class":127}," 0023cddd\n",[17,140,141,142,145],{},"An editor window will now open, containing a list of the commits that you just selected for manipulation. And don't be surprised because they are in ",[27,143,144],{},"reverse order",": in an interactive rebase session, Git will reapply the old commits, item after item – which means that reversing the order is correct from Git's perspective.",[17,147,148,152],{},[77,149],{"alt":150,"src":151},"Editor window with the selected commits","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398508/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/editor-window-start-ir%402x.png","\nEditor window with the selected commits",[17,154,155,156,159],{},"One other important thing to note about this editor window: ",[27,157,158],{},"you don't perform the actual manipulations here","! Or, in this concrete example, you do NOT go ahead and change the commit message here. Instead, you only mark the commit you want to change with an action keyword. In our case, because we want to change a commit’s message, we mark the line with \"reword\". If you then save and close this editor window, a new one will open, containing the old commit’s message. Now is the time to finally make your changes:",[17,161,162,166],{},[77,163],{"alt":164,"src":165},"Finally, we can make our changes","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398507/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/correct-commit-message.gif","\nFinally, we can make our changes",[17,168,169],{},"After saving and closing once more, the interactive rebase session is complete and our old commit message has been corrected!",[12,171,173],{"id":172},"combining-multiple-commits-into-one-using-interactive-rebase","Combining multiple commits into one using interactive rebase",[17,175,176,177,180],{},"Another use case for interactive rebase is when you want to ",[54,178,179],{},"combine multiple old commits into one",". Although, of course, the golden rule of version control applies: in most situations, it's beneficial to create more and smaller commits instead of a few big ones. However, as with everything, we might find that we have overdone this and now want to meld two or more old commits into a single one.",[17,182,183],{},"To make a concrete example, let's say we want to combine the following selected commits into a single one:",[17,185,186,190],{},[77,187],{"alt":188,"src":189},"Let's combine multiple commits into one","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398510/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/squash-selected-commits%402x.png","\nLet's combine multiple commits into one",[17,192,193],{},"Just like in our first case, we begin by starting the interactive rebase session at least at the parent commit of the one we want to manipulate.",[108,195,197],{"className":110,"code":196,"language":112,"meta":113,"style":113},"$ git rebase -i 2b504bee\n",[63,198,199],{"__ignoreMap":113},[117,200,201,203,205,207,209],{"class":119,"line":120},[117,202,124],{"class":123},[117,204,128],{"class":127},[117,206,131],{"class":127},[117,208,135],{"class":134},[117,210,211],{"class":127}," 2b504bee\n",[17,213,214],{},"Again, an editor window will open, listing that part of our commit history that we want to manipulate:",[17,216,217,221],{},[77,218],{"alt":219,"src":220},"Marking lines with \"squash\"","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398510/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/squash-mark-commit%402x.png","\nMarking lines with \"squash\"",[17,223,224,225,228],{},"The action keyword we are going to use here is called \"squash.\" And there's only one important piece of information you need to know about squash in order to use it: ",[27,226,227],{},"the line we mark up with the \"squash\" keyword will be combined with the line directly above",". That’s why, as you can see in my screenshot above, I’ve marked line #2 with \"squash\" in order to combine it with line #1.",[17,230,231],{},"We can now save and close the editor window and again watch and a new window appear: we are now asked to provide a commit message for the new commit that is created when combining those two old ones.",[17,233,234,238],{},[77,235],{"alt":236,"src":237},"Entering a new message for the new, squashed commit","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398510/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/squash-enter-new-message%402x.png","\nEntering a new message for the new, squashed commit",[17,240,241],{},"After saving and closing this editor window, you will see that a new commit was created that contains the changesets of both old commits. Voila!",[12,243,245],{"id":244},"fixing-a-mistake-with-interactive-rebase","Fixing a mistake with interactive rebase",[17,247,248],{},"Another use case for interactive rebase is when you found a mistake in one of your earlier commits. And it doesn't matter what exactly you messed up: you could have forgotten to add a certain change, should have deleted a file, or simply introduced a typo...",[17,250,251],{},"The natural tendency, in such a situation, is to simply create a new commit that corrects the mistake. But on the other hand, this will mess up our commit history: making an original commit, and then adding a \"band-aid\" commit just to fix some mistakes… that’s a messy way of working. Your commit history will soon become hard to understand, because it's littered with all those little \"quick fix commits\"!",[17,253,254],{},"This is where \"fixup,\" one of the tools that come with interactive rebase, comes in very handy. Fixup takes this \"quick fix\" commit, applies its changes to the original commit (thereby correcting it), and then gets rid of the band-aid commit:",[17,256,257,261],{},[77,258],{"alt":259,"src":260},"How \"fixup\" works","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398508/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/diagram-fixup.png","\nHow \"fixup\" works",[17,263,264],{},"After we're done, it looks as if there had never been a problem with our original commit! So let's walk through this using a practical example.",[17,266,267],{},"The first step is to do whatever is necessary to fix the problem: this could mean adding a new file, making changes to existing ones, deleting obsolete files... you \"just\" need to produce the changes that correct the mistake.",[17,269,270,271,274],{},"The next step is to commit these changes to the repository – but with a little extra: when making the commit, we are going to use the ",[63,272,273],{},"--fixup"," flag and tell Git the commit hash of our bad commit:",[108,276,278],{"className":110,"code":277,"language":112,"meta":113,"style":113},"$ git add corrections.txt\n$ git commit --fixup 2b504bee\n",[63,279,280,292],{"__ignoreMap":113},[117,281,282,284,286,289],{"class":119,"line":120},[117,283,124],{"class":123},[117,285,128],{"class":127},[117,287,288],{"class":127}," add",[117,290,291],{"class":127}," corrections.txt\n",[117,293,295,297,299,302,305],{"class":119,"line":294},2,[117,296,124],{"class":123},[117,298,128],{"class":127},[117,300,301],{"class":127}," commit",[117,303,304],{"class":134}," --fixup",[117,306,211],{"class":127},[17,308,309],{},"When you now take a look at the commit history, you will see that a pretty ordinarily looking commit has been created – probably not the magic and fireworks you would have expected. But if you take a closer look, you will see that something’s going on: the new commit has automatically been prepended with \"fixup !\" and the commit subject of our bad commit.",[17,311,312,316],{},[77,313],{"alt":314,"src":315},"The original commit and the fix commit","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398508/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/fixup_create-fix-commit%402x.png","\nThe original commit and the fix commit",[17,318,319],{},"The third step now is to start the interactive rebase session. Again, we choose the parent of our bad commit as the starting point...",[108,321,323],{"className":110,"code":322,"language":112,"meta":113,"style":113},"$ git rebase -i 0023cddd --autosquash\n",[63,324,325],{"__ignoreMap":113},[117,326,327,329,331,333,335,338],{"class":119,"line":120},[117,328,124],{"class":123},[117,330,128],{"class":127},[117,332,131],{"class":127},[117,334,135],{"class":134},[117,336,337],{"class":127}," 0023cddd",[117,339,340],{"class":134}," --autosquash\n",[17,342,343,344,347,348,351],{},"... and as the second part of the secret sauce, we are using the ",[63,345,346],{},"--autosquash"," flag. This option makes sure that we don't have to do ",[27,349,350],{},"anything"," in the editor window that is now open. Take a close look at the situation:",[17,353,354,358],{},[77,355],{"alt":356,"src":357},"Our fix commit is marked \"fixup\" and sorted to the right position","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398509/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/fixup_editor%402x.png","\nOur fix commit is marked \"fixup\" and sorted to the right position",[17,360,361],{},"You will see that Git automatically did two things for us:",[363,364,365,369],"ol",{},[366,367,368],"li",{},"It marked our band-aid commit as \"fixup.\"",[366,370,371,372,30],{},"It re-ordered the lines so that our band-aid commit appears directly below our bad commit. This is because fixup works exactly like squash in that it ",[27,373,374],{},"combines with the line above",[17,376,377],{},"In other words: there's nothing left to do for us but save and close the editor window.",[17,379,380],{},"Let's take another look at the commit history:",[17,382,383,387],{},[77,384],{"alt":385,"src":386},"A happy ending!","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398509/blog/Content%20Images/how-to-keep-your-git-history-clean-with-interactive-rebase/fixup_final-corrected%402x.png","\nA happy ending!",[17,389,390],{},"Not only does our originally bad commit now contain the changes from our band-aid commit. But on top of that, the ugly band-aid commit has disappeared from the commit history! Everything is nice and clean, just as if there had never been a problem!",[12,392,394],{"id":393},"discover-the-power-of-git-rebase-interactive","Discover the power of Git rebase interactive",[17,396,397,398,401,402,407],{},"There are lots of use cases for interactive rebase – and most of them in the department of “fixing mistakes”. For an overview of other useful things you can do, I recommend the ",[27,399,400],{},"free"," ",[21,403,406],{"href":404,"rel":405},"https://www.git-tower.com/learn/git/first-aid-kit?utm_source=gitlab&utm_medium=guestpost&utm_campaign=interactive-rebase",[],"\"First Aid Kit for Git\"",": it’s a collection of short videos (2-3 min per episode) that help you learn to undo mistakes using interactive rebase and other Git tools.",[17,409,410],{},"Editor's note: I had to use interactive rebase when reviewing this very post! One of my commits included an image that was greater than 1MB which is against the rules for GitLab website project. I had to go back and fix that commit to include a correctly sized image instead. Thanks for the lesson, universe! 😁",[12,412,414],{"id":413},"more-git-tips-and-tricks","More Git tips and tricks",[416,417,418,424,430],"ul",{},[366,419,420],{},[21,421,423],{"href":422},"/blog/15-git-tips-improve-workflow/","15 Git tips to improve your workflow",[366,425,426],{},[21,427,429],{"href":428},"/blog/partial-clone-for-massive-repositories/","How Git Partial Clone lets you fetch only the large file you need",[366,431,432],{},[21,433,435],{"href":434},"/blog/git-happens/","Git happens! 6 Common Git mistakes and how to fix them",[437,438,440],"h3",{"id":439},"about-the-guest-author","About the guest author",[17,442,443],{},[27,444,445,449,450,454],{},[21,446,7],{"href":447,"rel":448},"https://twitter.com/gntr",[]," is the CEO of ",[21,451,453],{"href":42,"rel":452},[],"Tower",", the popular Git desktop client that helps more than 100,000 developers around the world to be more productive with Git.",[17,456,457,458,463,464],{},"Cover image by ",[21,459,462],{"href":460,"rel":461},"https://www.pexels.com/@david-taljat-3748658",[],"David Taljat"," on ",[21,465,468],{"href":466,"rel":467},"https://www.pexels.com/photo/yellow-and-blue-line-on-gray-asphalt-road-5690623/",[],"Pexels",[470,471,472],"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 .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":113,"searchDepth":294,"depth":294,"links":474},[475,476,477,478,479,480],{"id":14,"depth":294,"text":15},{"id":48,"depth":294,"text":49},{"id":172,"depth":294,"text":173},{"id":244,"depth":294,"text":245},{"id":393,"depth":294,"text":394},{"id":413,"depth":294,"text":414,"children":481},[482],{"id":439,"depth":483,"text":440},3,"engineering","2020-11-23","Interactive rebase is one of Git’s most versatile tools. Here's how to use it to correct commit messages, fix mistakes, and more.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662593/Blog/Hero%20Images/title-image.png",{},true,"/en-us/blog/keep-git-history-clean-with-interactive-rebase",{"title":5,"description":486,"ogTitle":5,"ogDescription":486,"noIndex":489,"ogImage":490,"ogUrl":495,"ogSiteName":496,"ogType":497,"canonicalUrls":495},"https://about.gitlab.com/blog/keep-git-history-clean-with-interactive-rebase","https://about.gitlab.com","article","keep-git-history-clean-with-interactive-rebase","en-us/blog/keep-git-history-clean-with-interactive-rebase",[501,502],"git","tutorial","BlogPost","5pLGKXK8RwXPrUUOtS_i-DTwbFpwBEHJhqEZIMPvEcg",{"logo":506,"freeTrial":511,"sales":516,"login":521,"items":526,"search":852,"minimal":883,"duo":902,"switchNav":911,"pricingDeployment":922},{"config":507},{"href":508,"dataGaName":509,"dataGaLocation":510},"/","gitlab logo","header",{"text":512,"config":513},"Get free trial",{"href":514,"dataGaName":515,"dataGaLocation":510},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":517,"config":518},"Request a demo",{"href":519,"dataGaName":520,"dataGaLocation":510},"/sales/?contact-topic=request-demo","sales",{"text":522,"config":523},"Sign in",{"href":524,"dataGaName":525,"dataGaLocation":510},"https://gitlab.com/users/sign_in/","sign in",[527,556,655,660,774,830],{"text":528,"config":529,"menu":531},"Platform",{"dataNavLevelOne":530},"platform",{"type":532,"columns":533},"cards",[534,540,548],{"title":528,"description":535,"link":536},"The intelligent orchestration platform for DevSecOps",{"text":537,"config":538},"Explore our Platform",{"href":539,"dataGaName":530,"dataGaLocation":510},"/platform/",{"title":541,"description":542,"link":543},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":544,"config":545},"Meet GitLab Duo",{"href":546,"dataGaName":547,"dataGaLocation":510},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":549,"description":550,"link":551},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":552,"config":553},"Learn more",{"href":554,"dataGaName":555,"dataGaLocation":510},"/why-gitlab/","why gitlab",{"text":557,"left":492,"config":558,"menu":560},"Product",{"dataNavLevelOne":559},"solutions",{"type":561,"link":562,"columns":566,"feature":634},"lists",{"text":563,"config":564},"View all Solutions",{"href":565,"dataGaName":559,"dataGaLocation":510},"/solutions/",[567,590,613],{"title":568,"description":569,"link":570,"items":575},"Automation","CI/CD and automation to accelerate deployment",{"config":571},{"icon":572,"href":573,"dataGaName":574,"dataGaLocation":510},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[576,580,583,586],{"text":577,"config":578},"CI/CD",{"href":579,"dataGaLocation":510,"dataGaName":577},"/solutions/continuous-integration/",{"text":541,"config":581},{"href":546,"dataGaLocation":510,"dataGaName":582},"gitlab duo agent platform - product menu",{"text":584,"config":585},"Source Code Management",{"href":23,"dataGaLocation":510,"dataGaName":584},{"text":587,"config":588},"Automated Software Delivery",{"href":573,"dataGaLocation":510,"dataGaName":589},"Automated software delivery",{"title":591,"description":592,"link":593,"items":598},"Security","Deliver code faster without compromising security",{"config":594},{"href":595,"dataGaName":596,"dataGaLocation":510,"icon":597},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[599,603,608],{"text":600,"config":601},"Application Security Testing",{"href":595,"dataGaName":602,"dataGaLocation":510},"Application security testing",{"text":604,"config":605},"Software Supply Chain Security",{"href":606,"dataGaLocation":510,"dataGaName":607},"/solutions/supply-chain/","Software supply chain security",{"text":609,"config":610},"Software Compliance",{"href":611,"dataGaName":612,"dataGaLocation":510},"/solutions/software-compliance/","software compliance",{"title":614,"link":615,"items":620},"Measurement",{"config":616},{"icon":617,"href":618,"dataGaName":619,"dataGaLocation":510},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[621,625,629],{"text":622,"config":623},"Visibility & Measurement",{"href":618,"dataGaLocation":510,"dataGaName":624},"Visibility and Measurement",{"text":626,"config":627},"Value Stream Management",{"href":628,"dataGaLocation":510,"dataGaName":626},"/solutions/value-stream-management/",{"text":630,"config":631},"Analytics & Insights",{"href":632,"dataGaLocation":510,"dataGaName":633},"/solutions/analytics-and-insights/","Analytics and insights",{"title":635,"type":561,"items":636},"GitLab for",[637,643,649],{"text":638,"config":639},"Enterprise",{"icon":640,"href":641,"dataGaLocation":510,"dataGaName":642},"Building","/enterprise/","enterprise",{"text":644,"config":645},"Small Business",{"icon":646,"href":647,"dataGaLocation":510,"dataGaName":648},"Work","/small-business/","small business",{"text":650,"config":651},"Public Sector",{"icon":652,"href":653,"dataGaLocation":510,"dataGaName":654},"Organization","/solutions/public-sector/","public sector",{"text":656,"config":657},"Pricing",{"href":658,"dataGaName":659,"dataGaLocation":510,"dataNavLevelOne":659},"/pricing/","pricing",{"text":661,"config":662,"menu":664},"Resources",{"dataNavLevelOne":663},"resources",{"type":561,"link":665,"columns":669,"feature":763},{"text":666,"config":667},"View all resources",{"href":668,"dataGaName":663,"dataGaLocation":510},"/resources/",[670,703,730],{"title":671,"items":672},"Getting started",[673,678,683,688,693,698],{"text":674,"config":675},"Install",{"href":676,"dataGaName":677,"dataGaLocation":510},"/install/","install",{"text":679,"config":680},"Quick start guides",{"href":681,"dataGaName":682,"dataGaLocation":510},"/get-started/","quick setup checklists",{"text":684,"config":685},"Learn",{"href":686,"dataGaLocation":510,"dataGaName":687},"https://university.gitlab.com/","learn",{"text":689,"config":690},"Product documentation",{"href":691,"dataGaName":692,"dataGaLocation":510},"https://docs.gitlab.com/","product documentation",{"text":694,"config":695},"Best practice videos",{"href":696,"dataGaName":697,"dataGaLocation":510},"/getting-started-videos/","best practice videos",{"text":699,"config":700},"Integrations",{"href":701,"dataGaName":702,"dataGaLocation":510},"/integrations/","integrations",{"title":704,"items":705},"Discover",[706,711,716,721,725],{"text":707,"config":708},"Customer success stories",{"href":709,"dataGaName":710,"dataGaLocation":510},"/customers/","customer success stories",{"text":712,"config":713},"Blog",{"href":714,"dataGaName":715,"dataGaLocation":510},"/blog/","blog",{"text":717,"config":718},"Demo Hub",{"href":719,"dataGaName":720,"dataGaLocation":510},"/demo-hub/","demo hub",{"text":722,"config":723},"The Source",{"href":724,"dataGaName":715,"dataGaLocation":510},"/the-source/",{"text":726,"config":727},"Remote",{"href":728,"dataGaName":729,"dataGaLocation":510},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":731,"items":732},"Connect",[733,738,743,748,753,758],{"text":734,"config":735},"GitLab Services",{"href":736,"dataGaName":737,"dataGaLocation":510},"/services/","services",{"text":739,"config":740},"Contribute",{"href":741,"dataGaName":742,"dataGaLocation":510},"https://contributors.gitlab.com","contribute",{"text":744,"config":745},"Community",{"href":746,"dataGaName":747,"dataGaLocation":510},"/community/","community",{"text":749,"config":750},"Forum",{"href":751,"dataGaName":752,"dataGaLocation":510},"https://forum.gitlab.com/","forum",{"text":754,"config":755},"Events",{"href":756,"dataGaName":757,"dataGaLocation":510},"/events/","events",{"text":759,"config":760},"Partners",{"href":761,"dataGaName":762,"dataGaLocation":510},"/partners/","partners",{"config":764,"title":767,"text":768,"link":769},{"background":765,"textColor":766},"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":770,"config":771},"Read the latest",{"href":772,"dataGaName":773,"dataGaLocation":510},"/whats-new/","whats new",{"text":775,"config":776,"menu":778},"Company",{"dataNavLevelOne":777},"company",{"type":561,"columns":779},[780],{"items":781},[782,787,793,795,800,805,810,815,820,825],{"text":783,"config":784},"About",{"href":785,"dataGaName":786,"dataGaLocation":510},"/company/","about",{"text":788,"config":789,"footerGa":792},"Jobs",{"href":790,"dataGaName":791,"dataGaLocation":510},"/jobs/","jobs",{"dataGaName":791},{"text":754,"config":794},{"href":756,"dataGaName":757,"dataGaLocation":510},{"text":796,"config":797},"Leadership",{"href":798,"dataGaName":799,"dataGaLocation":510},"/company/team/e-group/","leadership",{"text":801,"config":802},"Handbook",{"href":803,"dataGaName":804,"dataGaLocation":510},"https://handbook.gitlab.com/","handbook",{"text":806,"config":807},"Investor relations",{"href":808,"dataGaName":809,"dataGaLocation":510},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":811,"config":812},"Trust Center",{"href":813,"dataGaName":814,"dataGaLocation":510},"/security/","trust center",{"text":816,"config":817},"AI Transparency Center",{"href":818,"dataGaName":819,"dataGaLocation":510},"/ai-transparency-center/","ai transparency center",{"text":821,"config":822},"Newsletter",{"href":823,"dataGaName":824,"dataGaLocation":510},"/company/contact/#contact-forms","newsletter",{"text":826,"config":827},"Press",{"href":828,"dataGaName":829,"dataGaLocation":510},"/press/","press",{"text":831,"config":832,"menu":833},"Contact us",{"dataNavLevelOne":777},{"type":561,"columns":834},[835],{"items":836},[837,842,847],{"text":838,"config":839},"Talk to sales",{"href":840,"dataGaName":841,"dataGaLocation":510},"/sales/","talk to sales",{"text":843,"config":844},"Support portal",{"href":845,"dataGaName":846,"dataGaLocation":510},"https://support.gitlab.com/hc/en-us","support portal",{"text":848,"config":849},"Customer portal",{"href":850,"dataGaName":851,"dataGaLocation":510},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":853,"login":854,"suggestions":861},"Close",{"text":855,"link":856},"To search repositories and projects, login to",{"text":857,"config":858},"gitlab.com",{"href":524,"dataGaName":859,"dataGaLocation":860},"search login","search",{"text":862,"default":863},"Suggestions",[864,866,870,872,876,880],{"text":541,"config":865},{"href":546,"dataGaName":541,"dataGaLocation":860},{"text":867,"config":868},"Code Suggestions (AI)",{"href":869,"dataGaName":867,"dataGaLocation":860},"/solutions/code-suggestions/",{"text":577,"config":871},{"href":579,"dataGaName":577,"dataGaLocation":860},{"text":873,"config":874},"GitLab on AWS",{"href":875,"dataGaName":873,"dataGaLocation":860},"/partners/technology-partners/aws/",{"text":877,"config":878},"GitLab on Google Cloud",{"href":879,"dataGaName":877,"dataGaLocation":860},"/partners/technology-partners/google-cloud-platform/",{"text":881,"config":882},"Why GitLab?",{"href":554,"dataGaName":881,"dataGaLocation":860},{"freeTrial":884,"mobileIcon":889,"desktopIcon":894,"secondaryButton":897},{"text":885,"config":886},"Start free trial",{"href":887,"dataGaName":515,"dataGaLocation":888},"https://gitlab.com/-/trials/new/","nav",{"altText":890,"config":891},"Gitlab Icon",{"src":892,"dataGaName":893,"dataGaLocation":888},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":890,"config":895},{"src":896,"dataGaName":893,"dataGaLocation":888},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":898,"config":899},"Get Started",{"href":900,"dataGaName":901,"dataGaLocation":888},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":903,"mobileIcon":907,"desktopIcon":909},{"text":904,"config":905},"Learn more about GitLab Duo",{"href":546,"dataGaName":906,"dataGaLocation":888},"gitlab duo",{"altText":890,"config":908},{"src":892,"dataGaName":893,"dataGaLocation":888},{"altText":890,"config":910},{"src":896,"dataGaName":893,"dataGaLocation":888},{"button":912,"mobileIcon":917,"desktopIcon":919},{"text":913,"config":914},"/switch",{"href":915,"dataGaName":916,"dataGaLocation":888},"#contact","switch",{"altText":890,"config":918},{"src":892,"dataGaName":893,"dataGaLocation":888},{"altText":890,"config":920},{"src":921,"dataGaName":893,"dataGaLocation":888},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":923,"mobileIcon":928,"desktopIcon":930},{"text":924,"config":925},"Back to pricing",{"href":658,"dataGaName":926,"dataGaLocation":888,"icon":927},"back to pricing","GoBack",{"altText":890,"config":929},{"src":892,"dataGaName":893,"dataGaLocation":888},{"altText":890,"config":931},{"src":896,"dataGaName":893,"dataGaLocation":888},{"title":933,"titleMobile":934,"button":935,"config":940},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":552,"config":936},{"href":937,"dataGaName":938,"dataGaLocation":939},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":941,"disabled":489},"release",{"data":943},{"text":944,"source":945,"edit":951,"contribute":956,"config":961,"items":966,"minimal":1176},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":946,"config":947},"View page source",{"href":948,"dataGaName":949,"dataGaLocation":950},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":952,"config":953},"Edit this page",{"href":954,"dataGaName":955,"dataGaLocation":950},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":957,"config":958},"Please contribute",{"href":959,"dataGaName":960,"dataGaLocation":950},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":962,"facebook":963,"youtube":964,"linkedin":965},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[967,1014,1068,1112,1144],{"title":656,"links":968,"subMenu":983},[969,973,978],{"text":970,"config":971},"View plans",{"href":658,"dataGaName":972,"dataGaLocation":950},"view plans",{"text":974,"config":975},"Why Premium?",{"href":976,"dataGaName":977,"dataGaLocation":950},"/pricing/premium/","why premium",{"text":979,"config":980},"Why Ultimate?",{"href":981,"dataGaName":982,"dataGaLocation":950},"/pricing/ultimate/","why ultimate",[984],{"title":985,"links":986},"Contact Us",[987,990,992,994,999,1004,1009],{"text":988,"config":989},"Contact sales",{"href":840,"dataGaName":520,"dataGaLocation":950},{"text":843,"config":991},{"href":845,"dataGaName":846,"dataGaLocation":950},{"text":848,"config":993},{"href":850,"dataGaName":851,"dataGaLocation":950},{"text":995,"config":996},"Status",{"href":997,"dataGaName":998,"dataGaLocation":950},"https://status.gitlab.com/","status",{"text":1000,"config":1001},"Terms of use",{"href":1002,"dataGaName":1003,"dataGaLocation":950},"/terms/","terms of use",{"text":1005,"config":1006},"Privacy statement",{"href":1007,"dataGaName":1008,"dataGaLocation":950},"/privacy/","privacy statement",{"text":1010,"config":1011},"Cookie preferences",{"dataGaName":1012,"dataGaLocation":950,"id":1013,"isOneTrustButton":492},"cookie preferences","ot-sdk-btn",{"title":557,"links":1015,"subMenu":1024},[1016,1020],{"text":1017,"config":1018},"DevSecOps platform",{"href":539,"dataGaName":1019,"dataGaLocation":950},"devsecops platform",{"text":1021,"config":1022},"AI-Assisted Development",{"href":546,"dataGaName":1023,"dataGaLocation":950},"ai-assisted development",[1025],{"title":1026,"links":1027},"Topics",[1028,1033,1038,1043,1048,1053,1058,1063],{"text":1029,"config":1030},"CICD",{"href":1031,"dataGaName":1032,"dataGaLocation":950},"/topics/ci-cd/","cicd",{"text":1034,"config":1035},"GitOps",{"href":1036,"dataGaName":1037,"dataGaLocation":950},"/topics/gitops/","gitops",{"text":1039,"config":1040},"DevOps",{"href":1041,"dataGaName":1042,"dataGaLocation":950},"/topics/devops/","devops",{"text":1044,"config":1045},"Version Control",{"href":1046,"dataGaName":1047,"dataGaLocation":950},"/topics/version-control/","version control",{"text":1049,"config":1050},"DevSecOps",{"href":1051,"dataGaName":1052,"dataGaLocation":950},"/topics/devsecops/","devsecops",{"text":1054,"config":1055},"Cloud Native",{"href":1056,"dataGaName":1057,"dataGaLocation":950},"/topics/cloud-native/","cloud native",{"text":1059,"config":1060},"AI for Coding",{"href":1061,"dataGaName":1062,"dataGaLocation":950},"/topics/devops/ai-for-coding/","ai for coding",{"text":1064,"config":1065},"Agentic AI",{"href":1066,"dataGaName":1067,"dataGaLocation":950},"/topics/agentic-ai/","agentic ai",{"title":1069,"links":1070},"Solutions",[1071,1073,1075,1080,1084,1087,1091,1094,1096,1099,1102,1107],{"text":600,"config":1072},{"href":595,"dataGaName":600,"dataGaLocation":950},{"text":589,"config":1074},{"href":573,"dataGaName":574,"dataGaLocation":950},{"text":1076,"config":1077},"Agile development",{"href":1078,"dataGaName":1079,"dataGaLocation":950},"/solutions/agile-delivery/","agile delivery",{"text":1081,"config":1082},"SCM",{"href":23,"dataGaName":1083,"dataGaLocation":950},"source code management",{"text":1029,"config":1085},{"href":579,"dataGaName":1086,"dataGaLocation":950},"continuous integration & delivery",{"text":1088,"config":1089},"Value stream management",{"href":628,"dataGaName":1090,"dataGaLocation":950},"value stream management",{"text":1034,"config":1092},{"href":1093,"dataGaName":1037,"dataGaLocation":950},"/solutions/gitops/",{"text":638,"config":1095},{"href":641,"dataGaName":642,"dataGaLocation":950},{"text":1097,"config":1098},"Small business",{"href":647,"dataGaName":648,"dataGaLocation":950},{"text":1100,"config":1101},"Public sector",{"href":653,"dataGaName":654,"dataGaLocation":950},{"text":1103,"config":1104},"Education",{"href":1105,"dataGaName":1106,"dataGaLocation":950},"/solutions/education/","education",{"text":1108,"config":1109},"Financial services",{"href":1110,"dataGaName":1111,"dataGaLocation":950},"/solutions/finance/","financial services",{"title":661,"links":1113},[1114,1116,1118,1120,1123,1125,1128,1130,1132,1134,1136,1138,1140,1142],{"text":674,"config":1115},{"href":676,"dataGaName":677,"dataGaLocation":950},{"text":679,"config":1117},{"href":681,"dataGaName":682,"dataGaLocation":950},{"text":684,"config":1119},{"href":686,"dataGaName":687,"dataGaLocation":950},{"text":689,"config":1121},{"href":691,"dataGaName":1122,"dataGaLocation":950},"docs",{"text":712,"config":1124},{"href":714,"dataGaName":715,"dataGaLocation":950},{"text":1126,"config":1127},"What's new",{"href":772,"dataGaName":773,"dataGaLocation":950},{"text":707,"config":1129},{"href":709,"dataGaName":710,"dataGaLocation":950},{"text":726,"config":1131},{"href":728,"dataGaName":729,"dataGaLocation":950},{"text":734,"config":1133},{"href":736,"dataGaName":737,"dataGaLocation":950},{"text":739,"config":1135},{"href":741,"dataGaName":742,"dataGaLocation":950},{"text":744,"config":1137},{"href":746,"dataGaName":747,"dataGaLocation":950},{"text":749,"config":1139},{"href":751,"dataGaName":752,"dataGaLocation":950},{"text":754,"config":1141},{"href":756,"dataGaName":757,"dataGaLocation":950},{"text":759,"config":1143},{"href":761,"dataGaName":762,"dataGaLocation":950},{"title":775,"links":1145},[1146,1148,1150,1152,1154,1156,1160,1165,1167,1169,1171],{"text":783,"config":1147},{"href":785,"dataGaName":777,"dataGaLocation":950},{"text":788,"config":1149},{"href":790,"dataGaName":791,"dataGaLocation":950},{"text":796,"config":1151},{"href":798,"dataGaName":799,"dataGaLocation":950},{"text":801,"config":1153},{"href":803,"dataGaName":804,"dataGaLocation":950},{"text":806,"config":1155},{"href":808,"dataGaName":809,"dataGaLocation":950},{"text":1157,"config":1158},"Sustainability",{"href":1159,"dataGaName":1157,"dataGaLocation":950},"/sustainability/",{"text":1161,"config":1162},"Diversity, inclusion and belonging (DIB)",{"href":1163,"dataGaName":1164,"dataGaLocation":950},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":811,"config":1166},{"href":813,"dataGaName":814,"dataGaLocation":950},{"text":821,"config":1168},{"href":823,"dataGaName":824,"dataGaLocation":950},{"text":826,"config":1170},{"href":828,"dataGaName":829,"dataGaLocation":950},{"text":1172,"config":1173},"Modern Slavery Transparency Statement",{"href":1174,"dataGaName":1175,"dataGaLocation":950},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1177},[1178,1181,1184],{"text":1179,"config":1180},"Terms",{"href":1002,"dataGaName":1003,"dataGaLocation":950},{"text":1182,"config":1183},"Cookies",{"dataGaName":1012,"dataGaLocation":950,"id":1013,"isOneTrustButton":492},{"text":1185,"config":1186},"Privacy",{"href":1007,"dataGaName":1008,"dataGaLocation":950},[1188],{"id":1189,"title":1190,"body":488,"config":1191,"content":1193,"description":488,"extension":1197,"meta":1198,"navigation":492,"path":1199,"seo":1200,"stem":1201,"__hash__":1202},"blogAuthors/en-us/blog/authors/tobias-gnther.yml","Tobias Gnther",{"template":1192},"BlogAuthor",{"name":7,"config":1194},{"headshot":1195,"ctfId":1196},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659488/Blog/Author%20Headshots/gitlab-logo-extra-whitespace.png","Tobias-Gnther","yml",{},"/en-us/blog/authors/tobias-gnther",{},"en-us/blog/authors/tobias-gnther","WgOPqQqKCIZhJhmIZ1jxQ6v3clPsCguQGMxL2xiRJnw",[1204,1213,1221],{"title":1205,"description":1206,"heroImage":1207,"category":484,"date":1208,"authors":1209,"slug":1212,"externalUrl":488},"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",[1210,1211],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1214,"description":1215,"heroImage":1216,"category":484,"date":1217,"authors":1218,"slug":1220,"externalUrl":488},"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",[1219],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1222,"description":1223,"heroImage":1224,"category":484,"date":1225,"authors":1226,"slug":1228,"externalUrl":488},"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",[1227],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1230},[1231,1245,1257,1269],{"id":1232,"categories":1233,"header":1235,"text":1236,"button":1237,"image":1242},"ai-modernization",[1234],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1238,"config":1239},"Get your AI maturity score",{"href":1240,"dataGaName":1241,"dataGaLocation":715},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1243},{"src":1244},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1246,"categories":1247,"header":1249,"text":1236,"button":1250,"image":1254},"devops-modernization",[1248,1052],"product","Are you just managing tools or shipping innovation?",{"text":1251,"config":1252},"Get your DevOps maturity score",{"href":1253,"dataGaName":1241,"dataGaLocation":715},"/assessments/devops-modernization-assessment/",{"config":1255},{"src":1256},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1258,"categories":1259,"header":1261,"text":1236,"button":1262,"image":1266},"security-modernization",[1260],"security","Are you trading speed for security?",{"text":1263,"config":1264},"Get your security maturity score",{"href":1265,"dataGaName":1241,"dataGaLocation":715},"/assessments/security-modernization-assessment/",{"config":1267},{"src":1268},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1270,"paths":1271,"header":1274,"text":1275,"button":1276,"image":1281},"github-azure-migration",[1272,1273],"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":1277,"config":1278},"See how GitLab compares to GitHub",{"href":1279,"dataGaName":1280,"dataGaLocation":715},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1282},{"src":1256},{"header":1284,"blurb":1285,"button":1286,"secondaryButton":1291},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1287,"config":1288},"Get your free trial",{"href":1289,"dataGaName":515,"dataGaLocation":1290},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":988,"config":1292},{"href":840,"dataGaName":520,"dataGaLocation":1290},1786803770975]