Skip to content

Instantly share code, notes, and snippets.

@lukestanley
Last active June 15, 2024 10:52
Show Gist options
  • Save lukestanley/b1986a209901c63cb2ac494b52d65527 to your computer and use it in GitHub Desktop.
Save lukestanley/b1986a209901c63cb2ac494b52d65527 to your computer and use it in GitHub Desktop.
List recently changed files that git is not tracking so you don't loose your files, with persistent filtering that's easy to change. So once you finally know what is missing, you can git add them and you should commit them. Useful when you have a big project you need to get more control of!
#!/usr/bin/env python3
"""
You can put this script somewhere you can easily run it.
You can mark it executable and run it directly on nix systems, e.g Mac, Linux etc.
Assuming you saved it to your home directory, mark it executable:
chmod +x ~/git_untracked_easy_filter.py
Usage:
`~/git_untracked_easy_filter.py`
Run in a shell, from the git directory you're working on.
"""
import os
import sys
import shelve
import fnmatch
import subprocess
DEFAULT_FILTERS = [
'*.key',
'*.tmp',
'filters.db'
]
def get_untracked_files():
result = subprocess.run(['git', 'ls-files', '--others', '--exclude-standard'], capture_output=True, text=True)
files = result.stdout.splitlines()
return files
def filter_files(files, filters):
filtered_files = []
for file in files:
if not any(fnmatch.fnmatch(file, f) for f in filters):
filtered_files.append(file)
return filtered_files
def sort_files_by_modified_time(files):
files_with_mtime = [(os.path.getmtime(file), file) for file in files]
files_with_mtime.sort()
sorted_files = [file for _, file in files_with_mtime]
return sorted_files
def load_filters():
with shelve.open('filters.db') as db:
filters = db.get('filters', None)
if filters is None:
filters = DEFAULT_FILTERS
db['filters'] = filters
return filters
def save_filters(filters):
with shelve.open('filters.db') as db:
db['filters'] = filters
def add_filter():
filter_value = input("Enter filter to add (e.g., *.json, *test*, weeks/*): ")
filters = load_filters()
if filter_value not in filters:
filters.append(filter_value)
save_filters(filters)
print(f"Filter '{filter_value}' added.")
def remove_filter():
filter_value = input("Enter filter to remove: ")
filters = load_filters()
if filter_value in filters:
filters.remove(filter_value)
save_filters(filters)
print(f"Filter '{filter_value}' removed.")
def list_filters():
filters = load_filters()
if filters:
print("Current filters:")
for f in filters:
print(f"- {f}")
else:
print("No filters applied.")
def show_list():
files = get_untracked_files()
filters = load_filters()
filtered_files = filter_files(files, filters)
sorted_files = sort_files_by_modified_time(filtered_files)
for file in sorted_files:
print(file)
def main():
try:
while True:
show_list()
print("\nMenu:")
print("1. List untracked files")
print("2. Add filter")
print("3. Remove filter")
print("4. List filters")
print("5. Exit")
choice = input("Choose an option: ")
if choice == '1':
show_list()
elif choice == '2':
add_filter()
elif choice == '3':
remove_filter()
elif choice == '4':
list_filters()
elif choice == '5':
break
else:
print("Invalid option. Please try again.")
except KeyboardInterrupt:
sys.exit(0)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment