 And as the first talk of the day, Bernhard will talk about Git DPM, which he thinks to be the better guild. Test. Thanks for being here so many, despite the early hour. I'll try to first talk about a little bit about Git and to give a short introduction what it can do and how it works and why I think that Git is the better method to manage patches in. And then I'll talk about Git DPM and how I think it can help you to use the power of Git for managing patches. Git is in version control system, version control system, store stuff, the files you have, who did commits, what was the commit about, and where the commit comes from. If you come from some other version control system, there are some things you have to unlearn first to be able to use Git. You can't store empty directories in Git because it only cares about files. There are no diffs between version but snapshots that are then compressed. So if you have learned in other version control systems that you have to be careful where to place things so that you don't get an enlarged size of your repository, you don't have to care about this when using Git. The commits are not a tree. Like in other version control systems, that's a big difference. And if you come from some other of the more sophisticated distributed version control systems, then you will most likely be quite confused by branches only being a local property. Let's start with history in Git. In Git, mostly only cares about commits. Each commit, as I said, has which state that your tree is and description and stuff, and some information with which commit is derived from which other commit. The big difference is that the only restriction with Git is that you have a cycle for the directed graph so you can build most strange things you can't even do in other version control systems, but let's first ignore them. Tag in Git is just a name. You give some commit and a branch in Git, and that's an important difference if you come from some other version control system, is also just a name for a commit, but one which can move around. Being in a branch is no property of a commit. If you come from a version control system that has this, you have to unlearn this first. But just something pointing to some commit. Merge is just creating a new commit which has two parents and usually some contents that are derived from both. Unlike some other version control systems, you can merge in all directions without Git carrying much. A special case is having a fast forward. It is also called... If you are in the branch and merge the master branch, there is nothing new to create. Just a branch moves somewhere else, points to somewhere else. Now, if we look how this strange thing could be done, you would have two commits with which you started, then someone did a merge of both, then someone else or the same person at another time merged them and then someone merged both merges and you can get the most absurd crafts as long as they are acyclic. For the rest of the talk, I don't do arrows, but the newer things are the more to the top they are. So the crafts go upwards. Storing stuff in Git. In this example, there is some directory with directory 3, with directory 1, directory 2 with files in it and usually on the left side, on the right side, how it is stored in Git. You have some commit. This commit points to a tree, which is just an sr1 hash. In my example, all sr1 hashes only have four tickets because if they had the real length, they wouldn't fit anywhere. In this example, you see, you have this 4b08 tree for head. This is just some object Git has, which references the subdirectories in it, which are again reference files and as you see, there was a file that was... There were two files with the same content in different subdirectories and Git only has to store it one time. So with Git, it hasn't built in the duplicifier. If you have one file and store it or introduce it in multiple branches or different places, this has almost no cost at all. An important thing with Git, which sometimes confuses people is the staging area, also called cache, also called index. The Git people miss a name and because the names are not so good, they invent a new name every six months. The idea is that this staging area is between your working directory and the commits you made. The idea is that if there is some change in the working directory here, someone has changed B and C in file 2 and year 2, then first you will move this into the staging area and already store the file in Git's file storage. And then if you do a commit, you usually take the current contents from the index and store this into a new commit. So you first come from the working directory, everything goes in the index, and the index is then stored as commit. On the one side, this is just some implementation detail, but it's also a very powerful concept. Just some things to look up. Usually if you do commits, most of the time you can ignore that there is an index and just give Git commit the minus a argument and it will look which file has changed and put them in the index first. But you already need it if you use some of the other Git comments, for example, Git div is for a beginner often a bit confusing because what you have to give it. Here in this example, I have done two commits an index which I visualize as some not yet done commit on top and the working directory also as sort of commit on top. And Git div usually shows the difference if you give it no arguments, it shows the difference between the index and your working directory. So changes you still have in your working directory which you have not yet decided that they should be in the next commit by putting them into the index. If you want to compare the index with something, you have to use Git div cache, which will then compare from the index by default to the head or you can just give some other commit. Or you can compare two different commits. So, yes. Another thing is the Git reset command. The Git reset command is also a little bit confusing because it does many different things. So they are all kind of the same but only when looked from the right angle. When Git reset resets something, if you tell it soft, it only will change the commit. So you undo and commit but your index is still the same. So everything you marked to be committed even if it was some partial contents you can then do again as commit. Git reset mixed resets the commit you are in and the index. So this is what you want to use when you have something prepared in your working directory. You have done and commit but now see you have committed too much. You don't want to put all of this in a commit. You use Git reset mixed and go back two steps and have again to decide what should be in the commit. And Git reset hard. Also resets the working directory. This is for the case when you decided what I changed here in my working directory is not worth it at all to be committed. And this all sounds a bit complex. It gets really powerful because Git allows you not only to decide changes of which files to commit but also to commit partial changes of a file with Git at minus p or Git at minus p and then some file name. Then you are presented with the different changes in this format of your files and can select for every chunk if you want to add it to your next commit or not. And you can even edit and stuff like this. Which allows you to first do some changes to your working directory to make the software work like you wanted and then decide which of the changes you did belong together and which should be in which commit. A big question is why do you want to make commits to represent logical pieces of changes? You could also just do some changes, commit, realize there is a bug, do some more changes, commit, do some changes, commit until it works. The problem is that then you have a history which only represents what you did. If you want to give this to some upstream to apply it, they will usually say not in this form because there are some, everyone has different views on how the history should look like but some important points is that most people like to have every commit in their published history to be in some working state. There is a feature called Git BSECT which means that you can do a binary search over your history to look where some bug was introduced. To use this, you have to have working commits because if half of your commits do not even compile or compile or you can't test them, then you can't really find where some bug were introduced. Most people prefer if different commits are about or if every commit is about only one thing and not many things together which makes it easier to review them to only include one of them at a time or to revert only some of them. And then, commits that you want some upstream to include in their history usually should have a proper description and I don't know about you but for me, writing a good description or good documentation is usually harder and needs some more twice than writing the code itself. You could just, if you want to have some nice commits which are suitable to include upstream you could just do your changes then put the changes in the working directory and do one commit after the other again but this is, if it's more than two commits you usually do some mistake have to start again from the beginning so you don't want to do this. So what you usually want or what I usually want to do if I prepare some commits for upstream to include is that I first do commits until it works and then beautify the commits by modifying the commits in Git. Let's start with some examples. The easiest way is if you just didn't commit and want to change something in this commit you forgot to add some file or some change then there is Git commit amend which just does a new commit but doesn't add this new commit on top of the current commit but replaces the current commit. Of course, only works with the last commit. Splitting a patch this, I did a bit more verbose as an example how using the index and everything works. First, usually if you do something more complex you want to remember the current state you are that you don't lose it. I prefer punches so Git punch old creates a new punch named old with the current state you are in. Then you tell Git the commit I'm just in should be reset so I use mixed to tell it I don't want the commit and please also reset the index, the staging area so that I can decide in you what should be in this commit. This, it's English name circumflex after the head means a head, circumflex one means the first parent of head. It's some Git notation. There are also other things. Then we in this case after the reset the change is only in our working directory and we have to tell Git which of those we want. In this case, splitting a patch we only want some changes so we tell it all modifications in file one all modifications in file two should be in the first commit to create then I can tell it from file three and file four present me all changes in there and ask me for every one if I want to include it or not then I can do a commit with only the changes I've marked this way here I'm using minus C old which means Git will use all the information like description, author, first commit time from the branch old I created in the beginning so I don't have to enter the description in you so I can also do without and what did you do? Then all files that were added to here let's do that then I'll do another commit with all the remaining changes with the minus A I tell it all files that you already know about and that are modified take the modifications without asking me about it this doesn't work for new files which the patch introduced so you have to add them first then you can for example ask it what are the modifications between my new state and the old I had old if I was just splitting a patch then there shouldn't be have been any difference of the result between both new commits and the one old commit then I can delete the temporary branch or if I made a mistake I just reset everything to the state I was before another important feature is git rebase which is quite powerful but like everything powerful also a bit dangerous git rebase means it takes some commits and rewards them to change that and applies them on something new for example here I have some branch feature which had already some things merged I have a new master this feature branch to be based on master then I'll switch to feature and create and tell it to rebase master this means there are new commits created for the change I had before and everything on top linear history what one has to think about if we're basing is that first merges are not rebased because git assumes a merge was only some resolving some conflicts if it had some changes on its own and by just applying the commits one by one you would get the same conflicts and have to resolve them there so git assumes you don't need this merge commit as some change and usually you won't need it and then in this example there is this branch pre on which feature was based on this is not moved at all git rebase only changes the current branch and if you rebase to something too long ago you lose all your intersections with other branches another thing is there is always new commits created so if you as next step rebase pre you get the commit another time but git will also usually use quite good magic so if you now rebase this branch feature on top of pre it will see that this commit with change.a was already there and doesn't has to create a new commit on top as you also see the old commits are no longer referenced by any name so they are lost and if nothing else points to them the next garbage collection will even delete them this gets even more powerful with git rebase interactive in this case we have some I have here an example with some master branch for commits on top on base and I do a git rebase minus I base then some editor opens be sure to use the editor environment variable if you don't like the default editor of your system and you get some explanation and some comments line here in the big example on top of it I magnified the important part this describes your commits the only thing a bit confusing is that it starts with the oldest commit and then goes to the newest which is quite the other way around like normally in git things go upward and not downward then in this editor you edit this file for example you the queen one you move to the top and change the pic with E for edit and the red one you move a bit to top and replace the pic with S for squash and then save this file then git will first pick the queen one committed on top on base as you choose edit here it will stop at this part and allow you to edit this patch so you can now this patch is your current head so you can amend it you can git what I described before to split something or do anything else you wanted then you tell git rebase continue and it will do the rest of this first it will apply the yellow patch then do the red commit and squash them together to one commit so this is like you can merge two patches or if some patch misses something you don't have to edit this patch but you can do a new commit with the missing parts and then merge those two parts together and then it does the last the last one and once it is finished is it also move the master branch in which you were before to the new result so I hope to have described enough of git what you can do to make it clear why I think that using this rebasing and amending and modifying commits is a very powerful thing to manage changes to give them some one to review or to include and as I mentioned patches for Debian package is in my eyes just the same preparing something you want upstream to include or sidestream or anyone else interesting and to review easily I think it's also good to manage patches for Debian package there are just two problems if you have such a patched and in this case patched 1.1 based on upstream 1 in this example for example you have rebased it on top of upstream 2 then amended the last commit so it was a new one for patch 2.2 then rebased the whole on top of upstream 2 then modified in this example the first commit so I have patch 2.3 the problem is that in this case with the rebasing branch you don't really have a history of what you did in some object and the other problem is that if you have a bunch head that is not fast forward that means that which doesn't just mean move to a child but in this way sidewalks means git is very bad about pushing it around the idea against this is to have some branch that just has all your rebased branches as parents this way everything is in your history and if you ask git where is this line in this file form with git blame you will just follow the history and find the first patch in which you change the line to the common state and what I like to do in this setup is in this branch merging in all the patched branches I think it's a good place to also manage your dbn directory to keep the changes to upstream and your dbn changes differently so after describing why I think git is a good idea for source packages and how I think it's used more most powerfully let's just get dpm is about the idea of git dpm is to manage patches in the way described before and the idea is to not change the workflow you have with normal source packages more than needed and to use git as natively as possible and hopefully as easily as possible as an example an important feature so one most of the time doesn't use it directly let's look at this example where you have some monster branch with your dbn changes have included in your upstream branch thus rebased your changes in this case two commits became one so hopefully upstream included the other one and in this case you want to need a merge you can and hope git will sort it all out but usually you want specific properties you want all your dbn directory from your old master directory and if upstream had dbn directory 2 you want to have it ignored everything else you want from upstream except gitignore, gitattributes and other stuff which usually edit them in the dbn branch to have all the files created while building a dbn package ignored and what I also like is the file deletions ignored so I can just delete files that are in the old star ball and upstream and the build process modified and don't have to care about them you can do this manually with git but it usually will tell you conflict, conflict, conflict and you have to resolve them and git merge patched twice to do this merge as I wanted as you have seen there are three branches to deal with an upstream branch and patched branch and master branch upstream has commits from upstream or imported or which tab will patched your patches and dbn branch to include your commits to dbn and to integrate everything so the upstream branch is what you get from upstream the patched branch will change like described before and the dbn branch will integrate everything and only the dbn branch in this case master needs to be shared and published because everything else is part of the history so usually you want to text stuff and also publish the text and the branches you can name like you want the default is that their master patched upstream or something patched upstream something so if you are in we see it's not we see patched this is patched we see it assumes it's in this one so if I run a bit a bit late um as I said the patched branch is rebased so it's usually not very good to have it pushed to your to some repository people pull from because you change it so often so the idea is of get dpm is to as you have it in the history anyway so if you look at the history and human can easily find it but to have a computer find it it's by git dpm also stored in its control file which is committed in dbn slash dot git dpm to this is that your patched branch is not directly visible only as part of the history but there you can find it even without git dpm and as you only have one master branch you can push and pull and in even cases even merge or let git pull merge it around if you want to do branch off for example a new stable branch because you need to do an upload to stable proposed updates you can just git checkout minus b the old version of the master branch and don't have to care about all the other magic the last important part is git dpm update patches the idea is that once you have this patched branch you also have all the information there to export in your source package some patch files under dbn patches and have a 3.0 quilt package with all the information you have so that anyone having a different workflow can just import your source package and just have all the patches this git dpm update changes just if it's needed it call merge patches first remove all the old patches creates the new one and remembers what state your patched bounces are so it can warn you if something is missing and it commits the results including the dbn patches directory having dbn patches in the git dbn patch means you can just check out of this branch looks like just the source package expected so everyone doing a git clone or a git checkout of some system can just run difficulty build package without any magic at all that they need the orage tar file around which you can do with bistin tar which git dpm can also commit for you and get out of it yes an upstream branch you can do many complex things with it the easiest way is just to import the orage tar into git even on top of the upstream commits because having a file times is no cost at all in git git dpm prepare just make sure an orage tar you have is available git dpm new upstream is a way to tell git dpm what that you have a new upstream that it should record it and the orage tar has so it can do something with it then instead of doing the rebase manually you can just tell it rebase patched so it will take your patched branch make it a real git branch and do the right rebase and then there is git dpm import new upstream which you just say this is an orage tar I got from upstream or created somewhere else I want to have it in my upstream branch on top of it I usually include some upstream history in this so this commit just is on top of the upstream history so with the git blame I see what I did what I did in patches and what upstream did to work with a patched branch I can do it manually with git or I do in git dpm checkout patched to create this this branch for me with the state it is and then I can do all the stuff and either called much patches or update patches or something else then there are some other helpers to do some funny things for me import dsc to import an old dsc file doing much of magic so one can even do I tried that most 1.0 packages with some patch system you have you can just import and have it in the history to work with them and even some more options because everyone likes to look at different so you can configure it most differently then the helpers for creating tags for your different branches so highly configurable because everyone likes to have the tags look different and another idea is we call dsc with which you have your db on branch in git you can just committed there and the dsc file in some branch and have even the original branch left so I think we have half a minute left for questions Is there some migrate git build package type repository to git dpm type like if you have some some dv on patches already you can do it and it will try to create and commit if with git build package you can have many different ways to handle your patches in some times it can create easily otherwise it's easiest if you do it yourself re-base them or bring them in some form with commits and then tell just git dpm this is my patched branch okay I fear the time is up and so thanks Bernhardt for your talk and in 15 minutes