<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Import Sys</title>
    <description>The latest articles on Forem by Import Sys (@import-sys).</description>
    <link>https://forem.com/import-sys</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3803491%2F3672685e-c5a6-4eec-a344-f6ad71ddb2b2.jpg</url>
      <title>Forem: Import Sys</title>
      <link>https://forem.com/import-sys</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/import-sys"/>
    <language>en</language>
    <item>
      <title>GIT Essentials</title>
      <dc:creator>Import Sys</dc:creator>
      <pubDate>Tue, 10 Mar 2026 16:05:35 +0000</pubDate>
      <link>https://forem.com/import-sys/git-essentials-20b5</link>
      <guid>https://forem.com/import-sys/git-essentials-20b5</guid>
      <description>&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/wYsTfkmZgcQ"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;You've been crunching day and night making sprite animation and finally you got it. Smooth and pleasant. With sight of relief you run your build... to find out that the character movement is broken! &lt;br&gt;
You checked the movement code and... it is gone!&lt;/p&gt;

&lt;p&gt;Before you go inventing a time machine stay awhile and listen. I will tell you how to do it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Table of content
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Installing git&lt;/li&gt;
&lt;li&gt;Init repository&lt;/li&gt;
&lt;li&gt;Repository trees&lt;/li&gt;
&lt;li&gt;Commits&lt;/li&gt;
&lt;li&gt;Commits history&lt;/li&gt;
&lt;li&gt;Remotes&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Luckily for us development is not always like running Diablo on hardcore without saves. You can and should save your progress during development, especially when you are  working in team with other developers. &lt;br&gt;
This is the point where  version control system (VCS) becomes handy. Today we are going to talk about git.&lt;br&gt;
Git  is a distributed version control system that track file changes over time, allowing you to become time and space traveler. &lt;/p&gt;


&lt;h3&gt;
  
  
  Installing git
&lt;/h3&gt;

&lt;p&gt;Installing git is very straight forward. Just visit the official web site downloads section &lt;a href="https://git-scm.com/install/linux" rel="noopener noreferrer"&gt;https://git-scm.com/install/linux&lt;/a&gt; and follow the instructions for your operating system.&lt;/p&gt;

&lt;p&gt;Once git installed let's check its version to verify installation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5xor81felc95q5fj93f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5xor81felc95q5fj93f.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, everything seems fine.&lt;/p&gt;




&lt;h3&gt;
  
  
  Init repository
&lt;/h3&gt;

&lt;p&gt;Let's start new project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;newgame
&lt;span class="nb"&gt;cd &lt;/span&gt;newgame

nvim main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This will be the next Diablo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For git, to be able to track changes in your project you have to init repository first. &lt;br&gt;
It can be done running &lt;code&gt;init&lt;/code&gt; command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create an empty repository inside your project folder. If you will list folder content you will find that &lt;code&gt;.git&lt;/code&gt; folder was created&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhl8kp7bxdywqfknx7lnn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhl8kp7bxdywqfknx7lnn.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what, you will ask?&lt;/p&gt;




&lt;h3&gt;
  
  
  Repository trees
&lt;/h3&gt;

&lt;p&gt;Yes, currently git did not track anything. &lt;br&gt;
But let's run &lt;code&gt;status&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faygbcihy1elv2lfqoyi9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faygbcihy1elv2lfqoyi9.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see the &lt;code&gt;main.py&lt;/code&gt; file is listed in the "Untracked files" section. At least we track that we do not track anything so far :)&lt;/p&gt;

&lt;p&gt;But what does it mean?&lt;br&gt;
Now is the most crucial part to understand what git is and how it actually work. &lt;/p&gt;

&lt;p&gt;Git is a file system with three states trees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Working tree&lt;/li&gt;
&lt;li&gt;Index &lt;/li&gt;
&lt;li&gt;HEAD&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and in any moment in time git tracks your project state in all three trees.&lt;/p&gt;

&lt;p&gt;Most command you will run will move your changes between this three states. &lt;/p&gt;

&lt;p&gt;Let's start unrolling all of this from the "Working tree". &lt;br&gt;
As it names suggests working tree is where work happens. You can edit, remove, move files and folders and git mostly does not care at all. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0f5vzq3vscr275dtciz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0f5vzq3vscr275dtciz.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But when you are good with work you have done you can stage the changes into the "Index" tree using &lt;code&gt;add&lt;/code&gt; command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and now if you will check the status&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnez2cuxi9amywnzwlt2p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnez2cuxi9amywnzwlt2p.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;you will see that &lt;code&gt;main.py&lt;/code&gt; is moved from the "Untracked files" to the "Changes to be commited".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fxgto7rlw3uwd4zomfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fxgto7rlw3uwd4zomfz.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's add some code to the &lt;code&gt;main.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NPC&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;greetings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;decard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NPC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Deckard Cain&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;greetings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Stay awhile and listen&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You see an old man&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;decard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;decard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;greetings&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see what git thinks about this update&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fun036g8atj53w7xq7ae2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fun036g8atj53w7xq7ae2.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you see another section: "Changes not staged to commit". &lt;br&gt;
It means that now you have both staged version in the Index tree as well as new changes in Working tree. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu6764uxy4ovazxw1bu4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu6764uxy4ovazxw1bu4.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can always check what has been changed by running diff command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gh"&gt;diff --git a/main.py b/main.py
index 5f7d3db..d9211a3 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/main.py
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/main.py
&lt;/span&gt;&lt;span class="p"&gt;@@ -1,3 +1,13 @@&lt;/span&gt;
&lt;span class="gi"&gt;+from dataclasses import dataclass
+
+@dataclass
+class NPC():
+    name: str
+    greetings: str
+
&lt;/span&gt; if __name__ == "__main__":
&lt;span class="gd"&gt;-    print("This will be the next Diablo")
&lt;/span&gt;&lt;span class="gi"&gt;+    decard = NPC(name="Deckard Cain", greetings="Stay awhile and listen")
+
+    print("You see an old man")
+    print(f"{decard.name}: {decard.greetings}")
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see git is watching you. &lt;/p&gt;

&lt;p&gt;If you are good with the changes you can stage it once again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpp4zghy8rzx2yxa1kw03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpp4zghy8rzx2yxa1kw03.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and checking the status you can see that there are no unstaged changes and also the diff is empty, meaning that all the changes are now in the Index tree.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnez2cuxi9amywnzwlt2p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnez2cuxi9amywnzwlt2p.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Commits
&lt;/h3&gt;

&lt;p&gt;So far so good. But I've promised you a time machine. &lt;br&gt;
This is the point where HEAD tree enters the scene.&lt;br&gt;&lt;br&gt;
You sure that you are done with greeting logic and want to make a save that you can load later if things will go wrong.&lt;br&gt;
You can move your staged changed to the HEAD tree using commit command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you run commit for the first time git will ask you to identify yourself, since every change should have it author&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Git will ask you to write the commit message. Usually in the commit message you describe features or fixes you have made so later you can easily find your save point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat: Deckard Cain said hello!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the commit message, and there you have it, your first commit!&lt;br&gt;
Let's take a quick look at the status&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it says &lt;code&gt;nothing to commit, working tree clean&lt;/code&gt; which means that now we starting with clean Working and Index trees. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xixkuletgqilwdae6zg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xixkuletgqilwdae6zg.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Let's go a bit crazy and delete the whole file!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; main.py

&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code is gone...  Diff renders all red...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gh"&gt;diff --git a/main.py b/main.py
&lt;/span&gt;&lt;span class="p"&gt;deleted file mode 100644
&lt;/span&gt;&lt;span class="gh"&gt;index d9211a3..0000000
&lt;/span&gt;&lt;span class="gd"&gt;--- a/main.py
&lt;/span&gt;&lt;span class="gi"&gt;+++ /dev/null
&lt;/span&gt;&lt;span class="p"&gt;@@ -1,13 +0,0 @@&lt;/span&gt;
&lt;span class="gd"&gt;-from dataclasses import dataclass
-
-@dataclass
-class NPC():
-    name: str
-    greetings: str
-
-if __name__ == "__main__":
-    decard = NPC(name="Decard Cain", greetings="Stay awhile, and listen")
-
-    print("You see an old man")
-    print(f"{decard.name}: {decard.greetings}")
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But now we have the time machine!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; HEAD

&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deckard is back!&lt;/p&gt;

&lt;p&gt;This particular command reset all trees to their states on the time of commit! But, we will get back to it later. &lt;/p&gt;




&lt;h3&gt;
  
  
  Commits history
&lt;/h3&gt;

&lt;p&gt;Let's quickly make another commit&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#... 
&lt;/span&gt;&lt;span class="n"&gt;akira&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NPC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Akira&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Wanna some heal, adventurer?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;#...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add changes to the commit&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And commit them&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat: add Akira"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have a new save point. But it doesn't mean that your previous commit is lost, you still can reset everything to the gold era of Deckard Cain!&lt;/p&gt;

&lt;p&gt;You can look at yours commit history using &lt;code&gt;log&lt;/code&gt; command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;commit 035e7ecf82bc3966332320c405b34645b5e7b591 (HEAD -&amp;gt; master)
Author: import sys &amp;lt;import.sys.dev@gmail.com&amp;gt;
Date:   Wed Mar 4 21:26:03 2026 +0200
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    feat: add Akira
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;commit 6d5d2d1d8c1d7c67b08f85067724c515b3534ef0
Author: import sys &amp;lt;import.sys.dev@gmail.com&amp;gt;
Date:   Wed Mar 4 20:51:02 2026 +0200
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    feat: Deckard Cain said hello!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You see both commits, and every commit has it unique ID. &lt;br&gt;
The HEAD tree is now pointing to the latest commit. &lt;/p&gt;

&lt;p&gt;Let's try to reset Akira changes. &lt;/p&gt;

&lt;p&gt;Usually you do not need the whole commit information, but only the ID and the commit message, so you can run log with --oneline prefix&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;035e7ec (HEAD -&amp;gt; master) feat: add Akira
6d5d2d1 feat: Deckard Cain said hello!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When executing reset command you can specify target commit id&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git reset &lt;span class="nt"&gt;--soft&lt;/span&gt; 6d5d2d1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Soft reset means that we reset only HEAD tree, leaving changes staged at Index tree, so you can re-commit them if you want to. But this is the story for another time &lt;/p&gt;




&lt;h3&gt;
  
  
  Remotes
&lt;/h3&gt;

&lt;p&gt;For now everything is happening on your local machine, and if you will accidentally  delete &lt;code&gt;.git&lt;/code&gt; folder you will lost all your commits and history. This is no good.&lt;/p&gt;

&lt;p&gt;To address this issue remotes exists. &lt;/p&gt;

&lt;p&gt;Remotes are basically servers where you can publish and store your commits. This can be literally any machine running git and accessible by the network. Or it can be platform like Github,  GitLab, Bitbucket and so on. &lt;br&gt;
We will talk about Github specifically, but the overall flow is identical to the every other platform.&lt;br&gt;
Also I will not cover github account registration and setup, because I will never finish this tutorial otherwise :)&lt;/p&gt;

&lt;p&gt;First of all let's check if we have any remotes configured for our repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As expected there are none of them, so let's go to the github.com and create remote repository.&lt;/p&gt;

&lt;p&gt;Now, as you have repository URL you can add remote to your local repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add origin git@github.com:import-sys/fantastic-fishstick.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Origin is just a default name for the default remote. &lt;br&gt;
Now if you check remotes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you will find that you have origin remote with two endpoints, for fetching and pushing commits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;origin  git@github.com:import-sys/fantastic-fishstick.git (fetch)
origin  git@github.com:import-sys/fantastic-fishstick.git (push)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, now the fun part.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You just pushed all your commits to the remote, so you can access your work history even if you will burn your computer (don't do it). As a bonus you can share code with other developers to collaborate on the project. Hello FOSS.&lt;/p&gt;

&lt;p&gt;Let's actually wipe everything, to prove the point&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; newgame
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your code is gone, you local git history is gone, but you can restore everything with a single command!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com:import-sys/fantastic-fishstick.git newgame

&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; newgame
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You've just cloned remote repository into local repository. &lt;br&gt;
Let's quickly check it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;newgame &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; 

git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the files and commits are there as if I have never delete them!&lt;/p&gt;

&lt;p&gt;If someone make another commits to the remote repository you can pull remote changes using following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git pull origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you are up to date with remote server, and in the log you will see the new commit&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, your remote is all set up.&lt;/p&gt;




&lt;p&gt;I know, it was tough. But understanding how you can manipulate git tree states is a key to more advanced git topics. Next time I will touch git topic we will discuss why trees are actually trees,  cover branches, merging, rebasing and other cool stuff.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>git</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Managing python virtual environments</title>
      <dc:creator>Import Sys</dc:creator>
      <pubDate>Wed, 04 Mar 2026 07:45:52 +0000</pubDate>
      <link>https://forem.com/import-sys/managing-python-virtual-environments-b0f</link>
      <guid>https://forem.com/import-sys/managing-python-virtual-environments-b0f</guid>
      <description>&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/SlrD8s3qg8U"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;If you are working on multiple projects you might have run into a problem — different projects requiring different versions of the same package.&lt;/p&gt;

&lt;p&gt;Today we are going to solve this with python virtual environments. You'll learn what they are, how to create and use them, and how they actually work under the hood.&lt;/p&gt;




&lt;h3&gt;
  
  
  Table of content
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Why to use virtual env&lt;/li&gt;
&lt;li&gt;What is the virtual env&lt;/li&gt;
&lt;li&gt;Create virtual env&lt;/li&gt;
&lt;li&gt;Activating virtual env&lt;/li&gt;
&lt;li&gt;Installing packages&lt;/li&gt;
&lt;li&gt;Deactivating virtual env&lt;/li&gt;
&lt;li&gt;Under the hood&lt;/li&gt;
&lt;li&gt;Removing virtual env&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why to use virtual env
&lt;/h2&gt;

&lt;p&gt;Imagine you are working on the two projects that both use the requests package as a project dependency. &lt;br&gt;
Now you will have a dilemma. &lt;br&gt;
If you installed requests package system-wide you will have to use same package version for the both projects. &lt;br&gt;
But, let's say your first project is in a production state and you have to stick with the specific package version. On the other hand while building your second project you want to use new features from the latest package release.&lt;/p&gt;

&lt;p&gt;Luckily you can use virtual environments!&lt;/p&gt;


&lt;h2&gt;
  
  
  What is the virtual env
&lt;/h2&gt;

&lt;p&gt;Virtual environment is the isolated python environment which allows you to manage dependencies separately.&lt;/p&gt;


&lt;h2&gt;
  
  
  Create virtual env
&lt;/h2&gt;

&lt;p&gt;Starting from the version 3.3 python provides built in mechanism to create virtual environments - venv module.&lt;br&gt;
Let's create virtual environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv ./virtualenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create virtual environment you have to run venv module specifying the path where virtual environment will be created.&lt;/p&gt;




&lt;h2&gt;
  
  
  Activating virtual env
&lt;/h2&gt;

&lt;p&gt;To be able to use specific virtual environment you have to activate it first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source &lt;/span&gt;virtualenv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using Windows you should use activation script for windows also available in the virtual env folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight postscript"&gt;&lt;code&gt;&lt;span class="nf"&gt;virtualenv\Scripts\activate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can see the terminal prompt has changed which means that you are working in the virtual environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynn92ux99fh6u9x0hgha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynn92ux99fh6u9x0hgha.png" alt="Active virtual environment"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Installing packages
&lt;/h2&gt;

&lt;p&gt;Package installation is exactly the same as without using virtual env. But now the packages are isolated to the current virtual environment. &lt;br&gt;
Also now it much safer to use pip directly since it bound to the specific python environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it have much more sense to provide requirements.txt file with the project since you can isolate packages for every project. And the installation process does not differs at all.&lt;/p&gt;

&lt;p&gt;Let's take the requirements file from the &lt;a href="https://dev.to/import_sys_e5dc095b85cbb9/installing-and-managing-python-packages-via-pip-17ka"&gt;PIP tutorial&lt;/a&gt; and install all the packages listed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs542z5dcswogtyls4d99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs542z5dcswogtyls4d99.png" alt="requirements.txt"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can check the installed packages in the virtual environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14y66fgwex7c5mby4otz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14y66fgwex7c5mby4otz.png" alt="installed packages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool, we have our packages installed. But how we make sure that they are isolated?&lt;/p&gt;




&lt;h2&gt;
  
  
  Deactivating virtual env
&lt;/h2&gt;

&lt;p&gt;Let's leave virtual environment by running deactivate command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;deactivate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that all the packages you've installed in the virtual environment are still there you just leave environment itself.&lt;/p&gt;

&lt;p&gt;And now if we check the packages list&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip list

python &lt;span class="nt"&gt;-m&lt;/span&gt; pip show numpy
python &lt;span class="nt"&gt;-m&lt;/span&gt; pip show openpyxl 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpiq98nn1wvt0stgv9haw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpiq98nn1wvt0stgv9haw.png" alt="packages not found"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You see that there are no packages that were installed inside the virtual environment.&lt;br&gt;
So you can tell isolation is working.&lt;/p&gt;


&lt;h2&gt;
  
  
  Under the hood
&lt;/h2&gt;

&lt;p&gt;Okay, but what is the magic actually?&lt;br&gt;
Let's activate our virtual environment once again and see how it works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source &lt;/span&gt;virtualenv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we run python or pip, what do we actually run? Let's check&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;which python 
which pip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3011f4t4ady6kgym6f9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3011f4t4ady6kgym6f9u.png" alt="python location"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see python interpreter as well as pip are located inside our virtual environment. &lt;/p&gt;

&lt;p&gt;Every time you create virtual environment you get dedicated python interpreter and package manager. &lt;/p&gt;

&lt;p&gt;Ok, but how does system knows that it should run this exact python interpreter?&lt;/p&gt;

&lt;p&gt;Let's check the PATH variable&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue1voi2k1ji723y5m1th.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue1voi2k1ji723y5m1th.png" alt="path env variable"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can tell our virtual environment now is the first location where system will look for the executable.  So activating virtual environment will automatically update your PATH variable adding virtual env location on top.&lt;/p&gt;

&lt;p&gt;Ok, cool. But what about packages? Let's see&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; virtualenv/lib/python3.14/site-packages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0xp1ugdaxay5v7kb02gp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0xp1ugdaxay5v7kb02gp.png" alt="packages folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here they are! All installed packages are stored inside virtual environment too.&lt;/p&gt;

&lt;p&gt;So that's how you can have different dependencies of different versions for your every project. Just create own virtual environment for every project!&lt;/p&gt;




&lt;h2&gt;
  
  
  Removing virtual env
&lt;/h2&gt;

&lt;p&gt;Obviously  you can remove virtual environment. You can simply remove the virtual environment folder, and that's it. But do not forget to deactivate it first&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;deactivate
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; virtualenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's virtual environments! Now you know how to keep your project dependencies clean and isolated.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>python</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Installing and managing python packages via PIP</title>
      <dc:creator>Import Sys</dc:creator>
      <pubDate>Tue, 03 Mar 2026 09:47:52 +0000</pubDate>
      <link>https://forem.com/import-sys/installing-and-managing-python-packages-via-pip-17ka</link>
      <guid>https://forem.com/import-sys/installing-and-managing-python-packages-via-pip-17ka</guid>
      <description>&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/szdSwEpo7qc"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;If you've been following Python tutorials, you've probably seen "just run pip install something" - but what IS pip? Where do packages come from? And why does this sometimes break?&lt;/p&gt;

&lt;p&gt;Today we're demystifying Python package management. You'll learn what pip is, how to use it, and how to avoid common mistakes that break your projects.&lt;/p&gt;




&lt;h3&gt;
  
  
  Table of content
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Introduction to the packages&lt;/li&gt;
&lt;li&gt;Introduction to the PIP&lt;/li&gt;
&lt;li&gt;Installing packages&lt;/li&gt;
&lt;li&gt;Removing the package&lt;/li&gt;
&lt;li&gt;Upgrading packages&lt;/li&gt;
&lt;li&gt;requirements.txt file&lt;/li&gt;
&lt;li&gt;Versioning&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction to the packages
&lt;/h2&gt;

&lt;p&gt;Imagine you have to fetch some URL on the internet. Sure, you can learn all the levels of the OSI model, write your own encapsulation/decapsulation implementation, learn HTTP specification and implement it. &lt;/p&gt;

&lt;p&gt;Or you can use the python requests library.&lt;/p&gt;

&lt;p&gt;Sounds good, but where will you get this library and packages? &lt;/p&gt;

&lt;p&gt;Simple. Python ecosystem has Python Package Index (PyPi) which is the official python packages repository.&lt;/p&gt;

&lt;p&gt;Open your browser and navigate to &lt;a href="http://pypi.org" rel="noopener noreferrer"&gt;pypi.org&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;Here you can search for the package you need. Just type requests in the search bar and navigate to the package details page.&lt;/p&gt;

&lt;p&gt;Here you can find all the information you need. Usage examples, authors, links to the documentation and the source code is available as well as installation instructions. &lt;/p&gt;

&lt;p&gt;As you can see we were instructed to use the pip command to install the package. But what is PIP?&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction to the PIP
&lt;/h2&gt;

&lt;p&gt;PIP is the standard package installer for python. &lt;br&gt;
Usually you don’t have to install PIP manually, but it is always a good idea to check if it installed and it version&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwvnceu3mm83og2pcrmz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwvnceu3mm83og2pcrmz.png" alt="Pip version"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If pip is not installed you can simply install it by running ensure pip module&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; ensurepip &lt;span class="nt"&gt;--default-pip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, PIP is working, so we can get back to the package installation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installing packages
&lt;/h2&gt;

&lt;p&gt;To install the package you will use the install command. Simple, isn’t it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;requests 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it. You’ve installed the package. Now you can use list command to check the installed packages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupoo1ei6jbfaypo3ghfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupoo1ei6jbfaypo3ghfw.png" alt="Pip list packages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the request package of the specific version is installed. &lt;br&gt;
But there are some other packages that we have not installed. Where did they come from?&lt;/p&gt;

&lt;p&gt;Let’s run command&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip show requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxh8h8igl5ualqflsdxl0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxh8h8igl5ualqflsdxl0.png" alt="requests package details"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This command will show details of the installed package. &lt;br&gt;
Take a closer look at the Requires section. &lt;br&gt;
Yes, the package can depend on other packages, and PIP will resolve these dependencies automatically!&lt;/p&gt;

&lt;p&gt;If you look at the details of the certifi package, for example, you will see that this package is required by the requests package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip show certifi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6ar8srlj67sj0i7zr9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6ar8srlj67sj0i7zr9x.png" alt="certifi package details"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Removing the package
&lt;/h2&gt;

&lt;p&gt;To remove the package you can use uninstall command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip uninstall requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note, that uninstalling a package will not remove its dependencies since other packages can be dependent on it. &lt;/p&gt;

&lt;p&gt;Let’s reinstall requests package once again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now let’s try to remove one of the requests package dependency&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip uninstall certifi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pip will allow you to remove it, but your “requests” package will be broken. You can use command check to check if you have some broken dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0jolprm7rfqedyl6prmy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0jolprm7rfqedyl6prmy.png" alt="pip check missing certifi package"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see PIP is notifying you that you are missing requests package dependency. You can fix it by reinstalling the requests package, or by installing a certifi package itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;certifi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, I would recommend reinstalling the requests package itself since it may be dependent on the specific version of the certifi package and installing another version may leave your setup broken.&lt;/p&gt;




&lt;h2&gt;
  
  
  Upgrading packages
&lt;/h2&gt;

&lt;p&gt;Let’s actually try it by installing an older version of the certifi package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip uninstall certifi 
python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="s2"&gt;"certifi==2015.4.28"&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; pip check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mljswnm0pms1r7qql4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mljswnm0pms1r7qql4u.png" alt="pip check wrong version"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PIP is telling us that we use an outdated version of the certifi package. &lt;br&gt;
But you can update the package specifying  --upgrade flag to the install command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; certifi
python &lt;span class="nt"&gt;-m&lt;/span&gt; pip check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see certifi package is successfully upgraded.&lt;/p&gt;




&lt;h2&gt;
  
  
  requirements.txt file
&lt;/h2&gt;

&lt;p&gt;We’ve almost done with the packages. But imaging you are working on a project that requires several dependencies. &lt;/p&gt;

&lt;p&gt;For example you need a requests package to fetch data, numpy package to analyze data and openpyxl to make XLS reports.&lt;/p&gt;

&lt;p&gt;Sure you can install this packages on your machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;requests numpy openpyxl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what if you have to share your code with someone else? Yes, you can message another developer and tell that he or she should install specific dependencies of specific versions, but this solution is not very scalable. &lt;br&gt;
Or I would say not scalable at all.&lt;/p&gt;

&lt;p&gt;Instead you can prepare requirements.txt file with all of the project dependencies and their versions.&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;requirements.txt

&lt;span class="nv"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;2.32.5
&lt;span class="nv"&gt;numpy&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;2.4.2
&lt;span class="nv"&gt;openpyxl&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;3.1.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now you can share this file as part of the project and install all the required dependencies using following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python &lt;span class="nt"&gt;-m&lt;/span&gt; pip list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvq47tv5flx0ub5fsnjc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvq47tv5flx0ub5fsnjc.png" alt="list of installed packages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can also upgrade all the packages listed in the requirements file adding –upgrade flag to the install command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt &lt;span class="nt"&gt;--upgrade&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Versioning
&lt;/h2&gt;

&lt;p&gt;During this talk I mentioned package versions several times. But what is the version after all?&lt;br&gt;
Python is mainly using two versioning schemes: semantic versioning and calendar versioning. I am gonna talk about semver here. &lt;br&gt;
So let's check requests package details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip show requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9rb1261w5lvtln32skk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9rb1261w5lvtln32skk.png" alt="request package details"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see we've installed requests version 2.32.5. &lt;br&gt;
Each number in the version has its meaning:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt; is the major version. Major version updates when you introduce public API changes and do not grant backward compatibility&lt;br&gt;
&lt;strong&gt;32&lt;/strong&gt; is the minor version. Minor version updates when you add functionality in backward compatible manner&lt;br&gt;
&lt;strong&gt;5&lt;/strong&gt; is the patch version. Patch version updates with the bug fixes and patches&lt;/p&gt;

&lt;p&gt;Why all this information matters?&lt;/p&gt;

&lt;p&gt;Well, when you see new version of the package released you almost always know is it safe to update. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If patch version changed - great, safe to update, just bug fixes. &lt;/li&gt;
&lt;li&gt;If minor version changed - usually it is safe to update, but I suggest spending some time reading release notes.&lt;/li&gt;
&lt;li&gt;if major version changed - well, better start new project :)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But let's say we want to automatically update patches and minor versions of the library, but do not want to switch to the major version.&lt;/p&gt;

&lt;p&gt;Let's get back to the our's requrements.txt file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8ovds0496plc0g5avff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8ovds0496plc0g5avff.png" alt="requirements.txt file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can specify exact version requirements we need. Let's update requests library version requirement&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;requests &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;2.32.5,&amp;lt; 3.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now we say that we want at least version 2.32.5 but not the 3rd major release.&lt;/p&gt;

&lt;p&gt;And every time you run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you will update requests library to the latest version of the 2nd major release. &lt;br&gt;
Isn't it cool?&lt;/p&gt;

&lt;p&gt;It's also worth to mention that you can (and should for production environments) lock the specific version of the package. Like we did for the numpy and openpyxl packages in the requirements.txt file. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz0iqaqqp3k4pzxjl61ky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz0iqaqqp3k4pzxjl61ky.png" alt="locked requirements"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope that now you have a better understanding of how to use third-party packages in your projects! &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>python</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
