WEBVTT

00:00.000 --> 00:13.400
Hello everyone, please welcome our next speaker, Vladislav, he will talk on efficient

00:13.400 --> 00:24.160
to get work flow for high stakes projects.

00:24.160 --> 00:30.800
One, one, checking the microphone, hello everyone, thank you for coming, a lot of great

00:30.800 --> 00:35.200
people today who open source community, I absolutely love it.

00:35.200 --> 00:43.160
So as was said, my name is Vlad, I am working in open source and appropriate proprietary

00:43.160 --> 00:48.400
development for about 12 years already by now, time is flying.

00:48.400 --> 00:54.680
And most of the time I spent working on databases, closed source open source, game development

00:54.680 --> 01:03.160
and right now in advertisement technology and today I wanted to present you some strategies

01:03.160 --> 01:09.400
of using Git that I found particularly helpful in my kind of work, in very specific conditions

01:09.400 --> 01:15.720
in which I was working my entire career and I mean projects which are big, they live long

01:15.720 --> 01:22.840
enough and it costs a lot to do anything wrong in them, that's why it's high stakes.

01:22.840 --> 01:29.080
And I want to emphasize firstly, like this disclaimer, there is no one right way to do

01:29.080 --> 01:34.120
Git, I am perfectly aware it's a very sensitive personal topic for a lot of people, what

01:34.120 --> 01:41.360
is right, what is wrong and I do not claim my today's points to be the absolute truth,

01:41.360 --> 01:46.520
it always depends on the project and even on people working on that project.

01:46.520 --> 01:53.200
So I'm just presenting one of the ways that I found is very useful in my specific context

01:53.200 --> 01:59.080
and I'm just hoping that you will keep an open mind, you maybe will try some of the stuff

01:59.080 --> 02:03.760
I will be showing, it long have to take it all at once, it's not a complete, like

02:03.760 --> 02:09.480
a modeling framework, you can just take some specific cheery pick, git cheery pick, some specific

02:09.480 --> 02:15.760
points out of it which you will find interesting useful for yourself and just keep an open

02:15.760 --> 02:17.760
mind.

02:17.760 --> 02:25.240
So most beneficial my presentation will be by the way to firstly students, juniors who are in the

02:25.240 --> 02:31.160
beginning of their career and they see a lot of ways to do version control, a lot of different

02:31.160 --> 02:38.120
ways inside every tool and they like feel maybe a bit lost, what is right to do, which

02:38.120 --> 02:43.960
tools are useful for what I hope, at least for Git, I can show you one of the ways which

02:43.960 --> 02:50.240
I believe probably was how it was supposed to be used and also for senior and lead developers

02:50.240 --> 02:58.880
as well who have pains in maintenance of their high stakes projects like to keep it clean.

02:58.880 --> 03:05.120
Our presentation today will follow this plan, first I will present you my context, like

03:05.120 --> 03:10.120
how it looks like, actually what I have to deal with every day, so maybe then you all

03:10.120 --> 03:17.280
better understand why certain things I propose to do in a specific way, then I will present

03:17.280 --> 03:26.120
you the points of my this efficient workflow, then I will show you benchmarks of git usage

03:26.120 --> 03:31.600
in the end to see how what effects you can get when you get it applied in real project

03:31.600 --> 03:37.880
with real people, like what people said when they try it what I propose and then we will

03:37.880 --> 03:45.040
make a short conclusion, this QR code right now is this link will not work after the presentation

03:45.040 --> 03:49.920
I will open it online and you will by the same link will be able to see it, so you can

03:49.920 --> 03:58.120
as well say it now, I will also show it again in the end, so the ways of Git they obviously

03:58.120 --> 04:04.520
highly depend on the type of project and people working on that project, there are like

04:04.520 --> 04:09.000
maybe infinite number of projects and people were using them in different ways but I was

04:09.000 --> 04:15.640
able I think to find free types which kind of allow to like almost every project you could

04:15.640 --> 04:22.880
put into one of those free categories, roughly speaking, first one we can call like enterprise

04:22.880 --> 04:28.360
it's usually something big, closed source, it might be not even in IT company like it

04:28.360 --> 04:34.800
could be a bank or something like this and they have a lot of people, a lot of code, old

04:34.800 --> 04:40.720
code, they have complicated processes how stuff is supposed to be done and they maybe use

04:40.720 --> 04:46.600
Git for like hooks, CI, CD but that's all, otherwise Git for such projects, typically

04:46.600 --> 04:50.680
from what I have seen is just a distributed code storage, they don't care if it's Git or

04:50.680 --> 04:56.960
whatever else, as long as you can hook CI, CD on it, they are good for them, need this

04:56.960 --> 05:01.680
to say that they don't care about Git history, clean cleanness of chemists or anything

05:01.680 --> 05:06.960
like that, probably this will not be very beneficial for them, another type we could call

05:06.960 --> 05:12.480
it a startup, it's similar to enterprise in a way that they also don't care too much about

05:12.480 --> 05:19.080
Git history or chemists because they move fast, they throw things out like throw things

05:19.080 --> 05:25.680
away, open, so keeping Git history doesn't make much sense, they will throw it away eventually

05:25.680 --> 05:30.520
anyway and there isn't even much to keep since and you'll start up right, team a small

05:30.520 --> 05:34.040
they are easily communicating with each other, a green one, things they don't need

05:34.040 --> 05:39.400
the stick procedures again, here Git is more like a distributed code storage, the last

05:39.400 --> 05:47.480
time though, it's a product, it's an open source, quite often, can also be closed source

05:47.480 --> 05:53.000
but more often it's making sense for open source, where you have middle size project, middle

05:53.000 --> 05:58.880
size team is not very frequently, chemists are being made like maybe at every hour on

05:58.880 --> 06:04.360
hot days but unlikely more than that, and the project is much more, it tends to leave

06:04.360 --> 06:12.200
long, it already leaves long, you can imagine like years, tens of years for more and it

06:12.200 --> 06:18.480
is also high stakes, meaning that cost of mistakes is very expensive, financial and

06:18.480 --> 06:22.800
repelational for the company, so you need to be very careful when you commit something

06:22.800 --> 06:27.800
into such projects, it might affect actual clients who are paying to you and you're very

06:27.840 --> 06:33.960
careful what you do, my talk is targeting the last one, the other ones might also find

06:33.960 --> 06:39.600
that useful but from experience it's in enterprise, you sometimes just cannot do things

06:39.600 --> 06:45.680
and start up they might not need those things but for product it will make all the sense,

06:45.680 --> 06:52.480
before we proceed I will show you a bit a little bit glimpse into my context in which

06:52.520 --> 06:58.160
I am operating, so it will be easier to for you a whole I hope to understand the following

06:58.160 --> 07:07.800
things, firstly I write code exclusively CNC++ which means it's well firstly it's very fast

07:07.800 --> 07:17.560
and nice low level fast company but yeah might be the short what I said, but also we do

07:17.560 --> 07:23.040
have problems like especially C++ is hard to cook it right, you can cook it right but

07:23.040 --> 07:27.480
it's very hard to do, one thousand different ways to do the same thing and you will have

07:27.480 --> 07:32.120
all sorts of issues, a runtime which you need to take care of compiler will not help you

07:32.120 --> 07:39.560
like memory leaks, data corruption, triads, racing, it's actually you need to keep to be

07:39.560 --> 07:45.200
alert all the time, also code size will be starting from hundreds of thousands of lines of

07:45.240 --> 07:53.440
code going over millions and really large projects and the code is old, my current code

07:53.440 --> 08:00.240
base it's over 20 years old which means it contains every single C++ standard that

08:00.240 --> 08:05.840
came out for all together, it's not like we're moving to next one they move all the

08:05.840 --> 08:13.120
old stuff, it also means that authors of this code are gone like they're not there, you

08:13.200 --> 08:19.040
can not ask them anything anymore, that's the main problem of the age of such project

08:19.040 --> 08:24.880
and you have a lot of legacy, somebody did it, you don't know what it is, why, how it works

08:24.880 --> 08:32.880
but it works, there is nobody to ask, and also call this high in every sense like it's

08:32.880 --> 08:39.680
high load, it's high scale like large scale and it's high stakes, to give you an example

08:39.680 --> 08:47.440
of high load like you add one byte to a struct, you think like it's not a big deal, it gets deployed

08:47.440 --> 08:53.040
on one of the clients, they get explosion of hundreds of gigabytes in a cluster for one byte in one

08:53.040 --> 08:59.280
structure or you add accidentally or you just decided it doesn't matter, code makes, it becomes

08:59.280 --> 09:04.240
simpler, you add it like a hundred microseconds load down, one millisecond load down on a hot path

09:05.040 --> 09:10.080
and then in the end of the month you will receive report from the client that every day during

09:10.080 --> 09:16.240
that month you had a opportunity to cost because of that tens of thousands of euros per day,

09:16.240 --> 09:23.600
this is what I mean as high stakes and high load, from all this I have concluded the two big

09:23.600 --> 09:31.360
points, firstly you cannot rely on people because they will like in the short one they will

09:32.320 --> 09:37.920
they will retire, they will burn out, they will be on vacation and suddenly you need to deal with

09:37.920 --> 09:43.680
an incident and they are not responding or they like literally move on to the next world so

09:43.680 --> 09:51.920
to say you cannot ask them, which means you need to rely on the code, code is the truth,

09:53.280 --> 09:57.440
what is written and the code is what will be running, some people might even be in the team

09:57.440 --> 10:02.400
and tell you what they think it's what how it's running but it might be not how it's running so

10:02.400 --> 10:08.400
code is the only source of truth, you must rely on it, you must keep it clean so it's readable and

10:08.400 --> 10:14.960
maintainable and story of that code so you can see how it was evolving and it will help you

10:15.760 --> 10:20.960
in the future and all of those points will be presenting next I wanted to unite and there's some

10:20.960 --> 10:27.200
catching name so it would not be just a bunch of like a pile of recommendations, I decided to call

10:27.200 --> 10:36.240
a Tatonic Flow similar to like git flow, one flow, this is atomic flow, this is like we will start

10:36.240 --> 10:43.040
with the most basic thing, it's most important point of my whole presentation, I show it first

10:43.040 --> 10:49.520
so you are still not too tired by the end of the presentation, if you get just this thing right,

10:49.600 --> 10:55.360
I will be already very happy and this third point is that commit should be atomic,

10:56.000 --> 11:02.960
hence is the name of the flow, atomic flow, this consists of several things, what does it mean atomic?

11:03.600 --> 11:12.320
In projects I work on, it's often very helpful when I can, for any line of code, tell why it was done,

11:12.960 --> 11:18.800
the key point is why, not what, what is done, I see it's the code, code is what,

11:18.800 --> 11:23.680
I can read it perfectly find myself, I don't need it narrated somewhere in the commit message

11:23.680 --> 11:29.200
or in the comment, like LLM's write, like to use those narrative comments all over the place,

11:30.160 --> 11:37.840
I need the why and the why, it's quite often noted in the code, for example why would we need it,

11:37.840 --> 11:43.680
imagine, I know there is a bug somewhere in some function, somehow I know it's in one function

11:44.640 --> 11:50.560
and then knowing the reason for the function's latest change, like in my case in 90% of cases,

11:52.400 --> 11:56.800
I know there is a bug in a function, I open it's latest commit, I see the bug instantly,

11:56.800 --> 12:02.160
like on review, maybe it was missed, you didn't know this was possible, then you deployed on

12:02.160 --> 12:06.720
production, it breaks, you open the commit and you see I, yes, how, this is how it would break,

12:07.920 --> 12:14.480
so I see the latest change and it gives me, can, can give me the, quite often, the answer, what

12:14.480 --> 12:23.280
went wrong and it would also help me extremely much, if the commit is small, imagine you found

12:23.280 --> 12:28.720
that commit, it touched the function like literally two lines of change and you like scroll through the

12:28.720 --> 12:34.160
commit, that's it another thousand lines of change, some code being moved, some other features

12:34.160 --> 12:39.200
being done, some bug fixes in the same commit, now you are not sure if this commit is at fault,

12:39.200 --> 12:44.000
like if this place is at fault, maybe the problem is somewhere else in the same commit,

12:45.040 --> 12:51.520
so it would be very helpful if this commit is small and is doing one thing in this one place,

12:51.520 --> 12:56.720
then it's less cognitive load for me to understand the, notice the bug, those two things,

12:57.520 --> 13:05.840
the ability to quickly see the why behind any change and the ability to understand that first

13:05.840 --> 13:14.480
from its small scope form the atomic commit, atomic like it's also the name is kind of self-explaning,

13:14.480 --> 13:21.120
right, the atomicity what does it mean in this case commit is self-sufficient, so it's alone,

13:21.120 --> 13:28.320
this commit is already functional unit of your code, it's self-explaning, doesn't need any other

13:28.320 --> 13:36.320
commits to be understandable, it brings value to the code and nothing can be removed from it without

13:36.320 --> 13:42.960
breaking it and nothing needs to be added to keep it stable, so it's like an atom, a stable unit

13:42.960 --> 13:50.320
of like your code evolution, it might still sound too abstract but think of it in another way,

13:50.400 --> 13:55.600
think of commit as functions, commit's are actually functions because functions are doing what,

13:55.600 --> 14:02.160
they take input, do something with it, produce output, commit does the same input of your commit as your

14:02.160 --> 14:10.320
old code base, by the of the function is the div, name of the function, is git commit, git message,

14:10.320 --> 14:16.880
and the title, output is the new version of your code and then it all makes sense, right,

14:17.040 --> 14:23.600
functions are supposed to be small, do one logical thing, be self-sufficient and understandable

14:23.600 --> 14:29.680
from their name, treat commits like this as well and then it's very easy to understand the reason why

14:29.680 --> 14:36.880
it can be useful, let's see some examples, this is a commit, real one, do not read the small text,

14:36.880 --> 14:44.000
I made it small intentionally, you don't need to read my slides, just look at, yeah, it also you can

14:44.000 --> 14:49.280
click on this link when you get the slides to see the original commit, it will be available in all

14:49.280 --> 14:57.040
examples, those links, so just pay attention to this, it's very small, it's like 11 lines of functional

14:57.040 --> 15:06.400
changes and some text, it fixes one bug, a crash and it's clearly visible from the title,

15:06.400 --> 15:12.000
then it does nothing else, explanation why, how did this bug happen, how did we miss it,

15:12.080 --> 15:17.440
what was the reason it's in those two paragraphs of text, very nice, easy to review,

15:18.640 --> 15:24.560
very clear to review and you'll also mention a stick at number, so if some context is not enough,

15:25.520 --> 15:29.680
the person can open the ticket number and see some may be a discussion or a history of

15:29.680 --> 15:35.280
older changes and times to fix it, can be very helpful, this was the previous version of the same commit,

15:35.280 --> 15:42.000
which was rejected, because firstly, what is it doing like, is it a performance regression,

15:42.000 --> 15:49.760
is it a crash fix, is it a logical issue being fixed, I have no idea, it says fix, what does it fix,

15:49.760 --> 15:57.520
I don't understand, don't see pipe push like, what happens if I push, and the commit message is empty,

15:57.520 --> 16:02.560
there is absolutely nothing and the commit is bigger, it has 15 lines, you know why,

16:02.640 --> 16:08.080
because the person who created it, didn't want to write a test, and decided just in case

16:08.880 --> 16:14.560
hack the same fix in multiple places, thinking that they might also break, but it was completely

16:14.560 --> 16:25.680
unnecessary, the original real fix like it's actually even 10 lines, 11, 11 works, another example,

16:26.400 --> 16:31.680
look at this mere chick quest, again you don't need to read everything, just look at the size,

16:31.760 --> 16:39.520
it's 15 commits, it's doing one thing though, it's not 15 different things, it's 15 steps

16:39.520 --> 16:46.640
of one, I think, in this case, bug fix, yes, and the average size of every commit is 50 lines,

16:48.400 --> 16:54.080
so the all fix the same bug, those commits is just, there was one bug, which was manifesting

16:54.080 --> 16:59.760
itself with multiple different places of the code base, unrelated places, but same bug,

16:59.920 --> 17:06.480
and we decided to fix this in one virtual quest, in multiple small commits, every commit with a test,

17:06.480 --> 17:10.800
fixes one place, the every commit is reviewable, deployable, and everything,

17:12.240 --> 17:19.360
and this is easy to review, like one commit, 50 lines just do it for every commit, and they have

17:19.360 --> 17:26.480
used them, if I would not care about commits, this would be over 1000 lines, which somebody would

17:26.480 --> 17:34.800
have to review all at once, and spot their 7 different places which were fixed, this is quite

17:34.800 --> 17:40.800
lot of work for review, including yourself, because first review you will be a self-review, obviously,

17:40.800 --> 17:48.480
before you submit it to somebody else, another example, a bit extreme, but still interesting to look at,

17:48.480 --> 17:54.960
it's one line change, 21 lines of explanation why this needs to be done,

17:56.560 --> 18:01.440
the question is why not put it in the code, this comment in this case it's specific to that

18:01.440 --> 18:07.600
commit, because this was a compilation fix, on the you can pileers, this bug didn't exist,

18:07.600 --> 18:14.000
on old can pileers, it would not come by also, you kind of could not miss it, and this message

18:14.000 --> 18:19.600
was for a review, really, not for the code maintenance, but still, it was very easy to review,

18:20.160 --> 18:24.480
you don't even need to contact the person who wrote this commit, it's just all right there,

18:25.120 --> 18:30.800
right in the text, from the commit, I miss it, you probably have already deduced that,

18:30.800 --> 18:36.560
if you do it the way I proposed, then any non-trivial merge request will require more than one

18:36.560 --> 18:40.880
can it, it's actually not very often when you can't get away with just single commit,

18:41.600 --> 18:50.000
on something untrivial, quite often you will need to do, you will need to touch surrounding code,

18:50.000 --> 18:57.520
prepare some base for your functional change, maybe move some code around, rename variables,

18:57.520 --> 19:02.320
functions, extract, code from one function to multiple other functions, right there, this like

19:04.560 --> 19:10.960
cleaning before you do the actual change, it can be actually extracted into separate committees,

19:10.960 --> 19:17.520
and to work with that, when you introduce the next concept, the daily work must be organized

19:17.760 --> 19:21.760
in so-called purchases or changes list or call it whatever you want,

19:23.760 --> 19:29.440
usually when you do it like this, you do multiple commits from top of each other in the beginning,

19:29.440 --> 19:35.440
which do the preparation, like some commits first, you will move code from one file to another,

19:35.440 --> 19:40.880
some commits will do rename throughout the whole code base, some commit will add the flag to some

19:40.880 --> 19:46.240
function and everywhere pass it as follows, so like in the next commit you can in some cases start

19:46.240 --> 19:51.920
passing it as true, those kind of like preparatory changes, which have no functional value,

19:51.920 --> 19:59.040
but they are needed to make the functional change later, this will firstly keep your,

19:59.040 --> 20:05.680
obviously history clean, secondly it also incredibly helps on the review, because the reviewer

20:05.680 --> 20:11.200
will be able to quickly go from the refactoring noise, it will be easy to review, right, you can

20:11.200 --> 20:17.200
you could move like 5,000 lines of code from one file to another, you will review it like just scroll through,

20:18.320 --> 20:22.560
or you even just look that the file names are okay, and then you don't need to look at the code,

20:22.560 --> 20:29.760
which is moved completely unchanged, right, those large commits can be easy to review, or a commit

20:29.760 --> 20:36.400
changes like 1,000 different lines, but all of them is a function rename, again the reviewer will just scroll

20:36.480 --> 20:41.840
for those changes easy without spending too much cognitive effort on this, but then reviewer

20:41.840 --> 20:49.520
issues the last commit, small functional atomic changes, and reviewer can spot issues in those changes

20:49.520 --> 20:55.120
easier because they are smaller, it's less context to keep it in mind than you can notice issues

20:55.120 --> 21:00.880
much easier, they will be more on the spot, but they will not be hiding in the huge pile of refactoring

21:00.880 --> 21:09.280
noise, right, let's see some examples, again this one will already show, it's a merge request,

21:09.280 --> 21:19.040
which fixes one bug in 7 different places, so it's 7 functional commits, small ones, and 8 commits,

21:19.040 --> 21:25.360
do preparatory refactoring can benchmark, they're extremely easy to review, those other 8 commits,

21:25.440 --> 21:31.840
it was like 50% of the complexity you cut away and make it very easy to review, and then the

21:31.840 --> 21:39.920
reviewer reviewer becomes faster and higher quality, reviewer will easier find problems in your work,

21:41.040 --> 21:46.640
and highlight them, this, imagine it would look like this, like you have commits, address,

21:46.640 --> 21:52.480
merge request comments, review fixes, benefits the IP, all this stuff, it's unreviewable,

21:52.560 --> 21:59.840
who are able to review the right side, will have to review it all at once, they will have no choice,

21:59.840 --> 22:04.320
reviewing this crap, it's one by one, those commits are on the review under reviewable,

22:06.000 --> 22:12.720
another example, also a bit extreme, but it shows the point well, it's 25 commits in one merge request,

22:13.280 --> 22:20.160
2,400 lines of changes without even tests, with test it's twice more, it was a very large

22:20.240 --> 22:26.320
single feature, which consists of multiple different parts, and on which I had to spend like a couple

22:26.320 --> 22:32.160
of months, I think, but it was actually very easy to review, because you know what, every commit,

22:32.160 --> 22:41.280
maximum was 350 lines, and more than half of the changes are refactoring, like preparatory changes,

22:41.280 --> 22:49.280
which were also very easy to review, another example, the latest one, also I like it a lot because

22:49.440 --> 22:54.400
shows how important it is to split code moves into separate commits, I heard the merge request

22:54.400 --> 23:05.280
with 14 commits, 3,300 lines of C code changed, but 2,500 of them were one commit, where code was moved

23:05.280 --> 23:11.360
unchanged, and reviewer can just go for that commit like in one minute, and then concentrate on

23:11.360 --> 23:18.080
small 13 remaining commits, and actually it helped us to find a few issues which I fixed,

23:19.040 --> 23:24.160
in the first round, I have to admit I was lazy, I did it in one commit, but then on review,

23:24.160 --> 23:29.280
I was told like, no, you have to split it, and then yeah, it actually helped.

23:31.360 --> 23:35.840
Technically, the previous points already make a huge difference, some people can even stop at that,

23:35.840 --> 23:40.400
like you can just take commit that a missity, or you can take commit that a missity and patch sets,

23:40.400 --> 23:45.520
but if you want more, there is actually more, which can help you even further, not even during

23:45.520 --> 23:55.200
development, but already during deployments and incident investigations, and I propose to keep

23:55.200 --> 24:04.560
Git history linear like one line. It means that when you look at Gitlog, or Gitlog is about

24:04.560 --> 24:10.560
example, I always align, but when you build a Git graph like, or you use UI for Git like Gitcrack and

24:10.560 --> 24:16.080
or whatever, you in projects sometimes see like there is a lot of parallel branches,

24:16.080 --> 24:22.240
somehow intersecting with each other, right? I propose even in those UI's, let's keep our history clean,

24:22.240 --> 24:29.120
one line. You still have development branches, don't take Gitmer on, like I don't suppose to

24:29.120 --> 24:35.200
have one branch, like for instance, per force version control system, it has no branches, like

24:35.280 --> 24:41.040
you do one commit and you need to merge it, there's no branches, but I still work on development

24:41.040 --> 24:47.440
branches, but the main branch development develop main master whatever it's, one line.

24:49.040 --> 24:53.280
You can even still have merge commits, it's just they will be also on the line, and they will be

24:53.280 --> 25:00.160
empty by the way, because you will have no conflicts. Imagine it's possible, imagine it's easily

25:00.240 --> 25:05.760
achievable. Let's see what we could get from that if it would be easily possible.

25:06.800 --> 25:12.800
Firstly, each commit on the Gitlog line is going to be right where it was actually applied,

25:12.800 --> 25:20.000
which is not like this when you use merge commits and you merge in your outdated branch into

25:20.000 --> 25:33.120
a branch which went forward. And it gives you 100% possibility to see historically what changes preceded

25:33.120 --> 25:38.960
which changes on your branch. The merge commits, it will not be so easily possible.

25:40.320 --> 25:45.680
Like when you have a graph, you have two parallel branches, how can you say which one was applied

25:45.760 --> 25:53.040
earlier, on the line it's 100% possible. You can also automatically from this, you can check out

25:53.040 --> 25:59.200
Git checkout any point on the line, it will pass test, it will compile, it will be deployable,

25:59.200 --> 26:05.680
and you know what it is going to be helpful for for Git by sect, you can get by sect even your

26:05.680 --> 26:11.920
production release, like imagine you might release, you have two Git tags, and you know this new

26:12.000 --> 26:18.880
release created a bug. Then you do Git by sect, type 1, type 2, you will find one commit which

26:18.880 --> 26:26.080
introduced the bug, you can revert it first and peacefully fix it later. With merge commits again,

26:26.080 --> 26:32.880
it will not be possible unless your history is linear. And then also coming from that, each commit

26:32.880 --> 26:40.000
is going to be transferable. It's a relatively unique use case, but I do have it in my open source

26:40.240 --> 26:47.680
project on which I am working on, but it's not mine. So we do have one long leaving branch,

26:47.680 --> 26:53.840
master branch, we have multiple long leaving branches, one for every long maintenance release,

26:53.840 --> 27:00.400
and we always commit to master first, and then we Git cherry pick to the other older releases where

27:00.400 --> 27:07.760
this fix makes sense. And this is almost always gets applied without any conflicts, we like

27:07.760 --> 27:14.800
literally have it automated in Git Hub CI. You can add a tag in our project like Backport version,

27:14.800 --> 27:20.880
and the bot will cherry pick those commits and merge them automatically. You don't even need human

27:20.880 --> 27:26.800
interaction if CI gets green, it gets merged. And this is because commits are atomic and transferable.

27:28.400 --> 27:34.880
And last but not least is that it's less cognitive load, like developing life of a developer is

27:34.880 --> 27:40.480
complicated enough. And we can simplify it a little bit at least in this case because you can think

27:40.480 --> 27:47.360
of your project as a line as a sequence of versions. It's just easier to think than in terms of

27:47.360 --> 27:52.160
graphs like which branch in parallel with which one was being developed and merged and so on.

27:53.040 --> 27:59.440
I do hope it sounds nice to you as it does to me. And for that to work, we just need one thing.

28:00.320 --> 28:07.200
Your branch is before the merge needs to be based on top of the target branch, like on the picture.

28:07.200 --> 28:12.960
It is so when you do just just did Git checkout minus B, but eventually it will not be so,

28:12.960 --> 28:19.360
because master will go forward, your branch becomes outdated and then like the most frequently used way

28:19.360 --> 28:25.680
is that you click like you type Git merge, it cannot be merged, you have conflict, then you have

28:25.680 --> 28:31.840
to resolve them and you still like Git merge continue, you do Git merge continue and then

28:32.640 --> 28:39.120
what happens is that your commits, the metadata of the commits gets inserted into the history,

28:39.120 --> 28:44.400
but the changes cannot be inserted into history. Your commits are not applied before some other

28:44.400 --> 28:50.800
commits, the changes, they will be all applied on top in this one merge commit.

28:51.360 --> 28:59.840
So, yeah, and you will also have to put all the conflict fixes in this merge commit.

29:00.400 --> 29:06.800
So, if some of your commits were outdated, they will stay outdated in the history and conflict fixes

29:06.800 --> 29:12.080
will be in the merge commit and it can be challenging to fix them all at once because

29:14.160 --> 29:20.000
when you have imagine a very large merge request, many commits, you merge it and you have

29:20.000 --> 29:25.280
multiple conflicts and multiple places of your patch, you will have to fix them all at once,

29:25.280 --> 29:32.160
it might be challenging to do compared to if you had a chance to fix them independently for

29:32.160 --> 29:39.360
every smaller commit. Also, you lose a commit or a miss it because your commits which you just merged

29:39.360 --> 29:45.920
inserted into history, they are not atomic anymore because they do not work without conflict fixes

29:45.920 --> 29:53.920
which are applied later in another commit. And finally, it's even unsafe to do that because when you

29:53.920 --> 30:00.240
imagine you have master brands and your brands, master brands is like it went forward, it has changes

30:00.240 --> 30:05.840
which your brands doesn't have. Your brands has changes that master doesn't have. Both of them can be

30:05.840 --> 30:11.600
green CI. When you merge them, you get a field version which never was running CI, you cannot

30:11.760 --> 30:19.040
be safely sure that it's safe to merge to deploy. So either you like risk it and merge it anyway

30:19.040 --> 30:24.400
or you first merge master into your branch and then merge your branch into master and then you have

30:24.400 --> 30:32.560
two merge commits. There are multiple solutions to that, at least two that I know, first is

30:32.560 --> 30:43.440
squash the commits. It's actually a nice simple way and so it's even available in GitHub and GitLab at

30:43.440 --> 30:49.200
least just like a checkbox and it will automatically squash your commits when you merge them into

30:49.200 --> 30:57.360
master into one commit. Then you do have it's very simple, you have linear history, it's just a little bit

30:57.520 --> 31:03.280
loss of the atomicity but still it's actually a nice simple way to get away with the linear history.

31:04.560 --> 31:12.480
There is another way. The alternative is you need to somehow change the base of your commits.

31:12.480 --> 31:20.640
So they are based on top of the latest master, right? Which means you need to re-based, change the base.

31:20.640 --> 31:26.560
Imagine it was like this, it was outdated and then you change the base and it becomes

31:27.680 --> 31:35.920
one line and then you can finally move it. It's called fast forward merge. So it's a merge,

31:35.920 --> 31:41.360
still but it has no merge commit because it's not needed. There is no conflict. You can just

31:42.080 --> 31:47.040
move your commits on top of the master branch and then it just works. The only problem here

31:47.760 --> 31:53.840
is that you need to learn how to re-based but it's worth it. Like look at my project a couple of years ago.

31:54.800 --> 32:02.560
This is a graph of my git log that I built of the project like it was in state two years ago

32:02.560 --> 32:08.480
before we started using photomic flow. Every vertical line is a merge commit which was applied

32:08.480 --> 32:15.680
later and then the tail goes down to the commits inserted into the history and then I was asking

32:15.680 --> 32:20.880
people how can you work with that and there was one guy who was saying like oh I like it so much

32:20.880 --> 32:26.000
it's so cool. I love merge commit and I was asking him like can you tell me what happened before

32:26.000 --> 32:31.680
what in this and he could not. He's like oh just give me one second just one second and he opens his

32:31.680 --> 32:37.760
git cracking UI and scrolls through all this hell. He couldn't tell me and I don't blame him because

32:37.760 --> 32:44.080
I also cannot read it. It's machine readable maybe but it's I can not read it. And this is how it looks

32:44.080 --> 32:50.720
now. It's a single line. We still have merge commit so I could not like completely destroy them.

32:51.280 --> 32:56.480
We use them on release but otherwise all the development between two releases it's always

32:56.480 --> 33:02.960
a line. Every commit compiles past a test it was at some point on a development branch but then

33:02.960 --> 33:10.320
you merge it is one line. Our team like actually extremely happy right now they previously they

33:10.400 --> 33:18.000
very much were like against it. They were resisting a lot but then eventually when they looked at

33:18.000 --> 33:24.720
how I do it they started using git as well. Now nobody of our team wants to go back ever to this.

33:27.920 --> 33:33.280
And some actual use cases where it helped like it's not just to keep things outestically nice and

33:33.280 --> 33:40.160
beautiful but with no use it has actual uses like free projects which I am working on or

33:40.320 --> 33:45.600
worked at. The freelance project where atomic flow comes from it's a trample database.

33:47.360 --> 33:52.720
They don't even know that they sit on a gold mine like they invented atomic flow. They never

33:52.720 --> 33:59.440
advertised it anywhere but I figured it's it's useful to show to people and the team did just

33:59.440 --> 34:06.400
little bit of statistics 15. Geetrevert calls in last four years just clear geetrevert. No context

34:07.360 --> 34:12.000
commits were in such clean state that you could pick a commit like a year ago

34:12.000 --> 34:18.720
reverted deployed and it works to remove a bag or like whatever or some feature gets deprecated to just

34:18.720 --> 34:25.040
reverted the feature or like sometimes daily sometimes at least weekly.

34:27.280 --> 34:33.040
People create a commit where they reference one or two older commits as and saying like oh here we

34:33.040 --> 34:39.760
do this fix because in some previous commit that was missed and they give a commit hers or like

34:40.800 --> 34:46.080
you like sometimes your reference things or when you work on a feature you can reference previous

34:46.080 --> 34:52.320
attempts to implement this feature in previous commits literally put get get hash in the commit

34:52.320 --> 34:58.000
messes and some UI like GitHub get lab they can even make it clickable they will highlight it

34:58.000 --> 35:04.000
and you can navigate it click by click to see the story of a certain feature or a certain bag

35:04.000 --> 35:12.960
how it was evolving through multiple commits in time. At my current main job we started using

35:12.960 --> 35:18.720
git blame almost daily because as I said we have very old code base we have multiple features

35:18.720 --> 35:24.720
which we don't even know how they work. Nobody touched them like in literally 10 years. You open

35:24.720 --> 35:30.720
some function it was not touched for 10 years. You have nobody to ask for. How it was done you

35:30.720 --> 35:35.280
opened like git blame sometimes you are lucky there is a like ticket number or something. In the

35:35.280 --> 35:43.040
fresh code you always use git blame and find something helpful and we use three simply git by

35:43.040 --> 35:48.880
sect and git revert for two performance degradation rewards very quickly after deployment we were

35:48.960 --> 35:55.760
able to find them with bisect and revert and various bugs in production and in development as

35:55.760 --> 36:00.560
well. Like sometimes you develop a branch you see it's not passing tests you can get bisect

36:00.560 --> 36:05.440
your own development branch to find in which commit you introduce the bug before you have in

36:05.440 --> 36:12.720
the request area and also I worked at the game they have company where investigations using

36:13.600 --> 36:18.560
like they don't use git they use per force but it has something similar to git by sect

36:18.560 --> 36:25.440
git blame and there it was happening daily like every day team over 100 people somebody was using

36:25.440 --> 36:32.560
it to find the reason for a bug or reference something for a new feature or whatever so the principles

36:32.560 --> 36:38.000
they don't just buy just in git is just in git it's very nice to have branches but in per force

36:38.000 --> 36:44.960
for example it also quite applicable so let's assume cleaner history at cool we wanted which means

36:44.960 --> 36:51.440
we want three base and about that I wanted to talk slightly more most of what I agree today is usually

36:51.440 --> 36:56.640
most I talked today is usually agreed with but people are afraid of rebase for some reason even

36:56.640 --> 37:02.880
though it's easier than merge but it's worse when you make your branch you will not get a clean

37:02.880 --> 37:09.280
history right away right you will your branch quite often will look like this like formatting fixed

37:09.280 --> 37:14.880
part one VIP all the stuff and you want to make it nice like ideally you would want to reward

37:14.880 --> 37:20.480
some things maybe squash them together and then suddenly you have a nice have nice commits you

37:20.480 --> 37:27.120
will not get it from the start or like it will be very rare so you usually need to be find the way

37:27.120 --> 37:33.120
to restructure your commits before submitting them for a review and rebase can also help you

37:33.120 --> 37:39.120
even then because rebase it's not just changing the base rebase should is actually re-apply

37:39.120 --> 37:46.800
rebase re-applies the commits on a base that you give it but this base can be anything it doesn't

37:46.800 --> 37:53.680
even have to be another branch you know you can rebase your own branch on yourself on all itself

37:54.080 --> 37:59.200
and for there is a command for that get the base minus i with which you can do quite a lot of stuff

38:00.240 --> 38:06.640
for example take this dirty branch i do a base this branch on itself and minus i it means

38:06.640 --> 38:12.320
interactive it will open text editor of your choice like nano beam or some lime vscode whatever you

38:12.320 --> 38:19.760
can it's configurable where it will show you the plan of rebase every line means like the git

38:19.760 --> 38:25.200
when even you save this file it will apply those commits pick means applying this case

38:25.200 --> 38:30.080
but you can change this plan it's a text editor so you can reorder some lines you can change the

38:30.080 --> 38:34.800
action like you can squash them commits you can change message of some of them you can stop in

38:34.800 --> 38:41.600
between commits and add the new commit there you can delete some commits and then you save it and

38:41.600 --> 38:48.080
git will apply this plan and you will get a nice branch there is obviously much more to say about

38:48.080 --> 38:55.200
rebase i will not be saying more about this but i created tutorial which helps teams to learn rebase

38:55.200 --> 39:00.400
when they never used it before by this link again it's clickable later on the slides for the

39:00.400 --> 39:10.960
is link at the bottom where i created a project with a with a very dirty branch and instructions

39:10.960 --> 39:16.080
how you can turn this branch into a diamond it will look very clean you just follow the steps

39:16.160 --> 39:21.760
where i show you how you can reorder commits add new commits remove commits from the middle of your

39:21.760 --> 39:29.680
branch and so on this was the entire background of atomic flow now a quick through the benchmarks

39:30.960 --> 39:36.160
benchmarks here like i usually do technical presentations where i can benchmark things like

39:36.160 --> 39:42.480
measure latency rps here it's very subjective because it's about people about processes but i

39:42.800 --> 39:49.280
made a survey and i was asking people from different companies different titles what do they think

39:49.280 --> 39:55.040
about specifics like of their daily work with git and starting from juniors to multiple city

39:55.040 --> 40:00.320
who's open source close source project center price start apps products and this is what i

40:00.320 --> 40:08.000
got i will show you a median opinion on every topic that i was a survey firstly how much does it

40:08.000 --> 40:13.920
cost to do atomic flow some people reported like median 10% of development time they spend on

40:14.480 --> 40:20.000
rebase and atomicity polishing but they sounded like a lot to me then i asked how much in minutes

40:20.560 --> 40:27.040
people were able to quantify less than 30 minutes per task people who do it a long time already they say

40:27.040 --> 40:33.360
like one five minutes per task it obviously depends on the size of the change but this is like

40:33.360 --> 40:41.120
median answer it also was reported that atomic flow boosts the project development speed in general because

40:41.120 --> 40:48.560
you might pay if you additional minus direct development but you get an incomparably faster and higher

40:48.560 --> 40:54.320
quality reviews which means you will have less bugs less investigations faster investigations when

40:54.320 --> 41:01.520
you are trapped because of linear history also atomic flow as expected was reported high value for

41:01.520 --> 41:07.120
product but not so for enterprise and startup this is completely understandable as i said my way

41:07.120 --> 41:13.520
is not the most right way is just one of the ways which seems suitable for some products which

41:13.520 --> 41:21.200
reported it as high value then i was particularly interested in speed of reviews and people who

41:21.200 --> 41:26.960
like i had project right now unique situation people were using old ways and switched to atomic

41:27.120 --> 41:32.160
flow and i was asking them how do they feel about reviews now people quantify it all of them

41:32.160 --> 41:38.720
quantified it as faster now but they quantified between one and half to five times faster because of

41:38.720 --> 41:46.800
how much easier it becomes and then i was curious how people review stuff to master price some people

41:46.800 --> 41:51.520
look at whole diff and then at individual commits some people look at individual commits then whole diff

41:51.600 --> 41:58.560
some people do it just this way or just the other way but in the end basically like over 70% of

41:58.560 --> 42:04.800
people do like to look at individual commits when they can also linear history was reported better

42:04.800 --> 42:09.840
in every sense by the reason well when they have when when people have a choice like sometimes you

42:09.840 --> 42:16.560
don't have a choice but people said they would like to use it when they can also to mice for prices

42:16.560 --> 42:21.360
well get blame and get by sector peer to be quite popular tools because i thought always it's like

42:21.360 --> 42:27.040
niche commands but no most of people i asked use them daily or weekly or at least try to use

42:27.840 --> 42:34.560
then i was curious the use of merge commits several people unrelated to each other synchronously

42:34.560 --> 42:42.560
reported to me the same word hate when they were describing how they what did they think about merge

42:42.640 --> 42:48.800
commits this tells you how convenient they are so those are basically where where all the points

42:48.800 --> 42:54.320
i was asking you can take a photo or something on this slide it's like a summary of the whole presentation

42:54.320 --> 43:02.160
you can say to share it when you don't want to scroll for everything i will give you five more seconds

43:02.160 --> 43:09.680
to take a photo then we move on one two three four five you can also likely trope in a

43:09.920 --> 43:16.400
way by the QR code and the short summary again the atomic commits smallest logical unit nothing can

43:16.400 --> 43:21.600
be removed navigate needs to be added patch sets on development branch you deal build a patch set you

43:21.600 --> 43:27.680
sent a review a patch set no single large commit linear history just remove merge commits you will get linear

43:27.680 --> 43:33.440
history as simple as that and interactive rebase is your daily tool to achieve in coldies

43:34.320 --> 43:40.880
the conclusion there is no just atomic flow there is also other ways atomic flow today we focus on

43:40.880 --> 43:47.520
atomicity history reviews and language of the history and project there is also one flow which is

43:48.640 --> 43:56.000
what expired me to do this talk it's built by a guy Adam Ruka and he wrote like some many years ago

43:56.000 --> 44:01.520
he wrote an article basically to summarize how much he hates merge commits and then it evolved in

44:01.520 --> 44:08.640
a series of articles where he designed this one flow of using git it focuses more on simplicity

44:08.640 --> 44:14.320
so prehorse squash for example branching structure like how many actual long-leaving branches

44:14.320 --> 44:20.240
you're supposed to have for what atomic flow doesn't care about that how you should do releases

44:20.240 --> 44:24.480
linearity of the changes and there is of course git flow which tries to do kind of everything

44:24.560 --> 44:32.160
git once and this is why it's differently cooked everywhere this was the end thank you for

44:32.160 --> 44:39.200
your attention again this QR code you can use later to open this presentation

44:40.160 --> 44:55.920
you can connect with me on the like development then professional social networks and

44:55.920 --> 45:02.960
youtube channel where I talk more about system programming, operating systems C and C++

